Get rid of netiso. It hasn't compiled in some time, there are no
applications, and nobody uses it.
This commit is contained in:
@@ -1,298 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)argo_debug.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: argo_debug.h,v 1.3 1994/08/21 06:14:11 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_ARGO_DEBUG_H_
|
||||
#define _NETISO_ARGO_DEBUG_H_
|
||||
|
||||
/*****************************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* $Header: /home/ncvs/src/sys/netiso/argo_debug.h,v 1.3 1994/08/21 06:14:11 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/argo_debug.h,v $
|
||||
*/
|
||||
|
||||
|
||||
#define dump_buf(a, b) Dump_buf((caddr_t)(a), (int)(b))
|
||||
|
||||
/***********************************************
|
||||
* Lint stuff
|
||||
**********************************************/
|
||||
#if defined(lint)
|
||||
/*
|
||||
* lint can't handle the flaky vacuous definitions
|
||||
* of IFDEBUG, ENDDEBUG, etc.
|
||||
*/
|
||||
#endif /* defined(lint) */
|
||||
|
||||
/***********************************************
|
||||
* DEBUG ON:
|
||||
**********************************************/
|
||||
#ifndef ARGO_DEBUG
|
||||
#define ARGO_DEBUG
|
||||
#endif /* ARGO_DEBUG */
|
||||
|
||||
|
||||
#ifdef ARGO_DEBUG
|
||||
/*
|
||||
#ifndef TPPT
|
||||
#define TPPT
|
||||
#endif TPPT
|
||||
|
||||
#ifndef TP_PERF_MEAS
|
||||
#define TP_PERF_MEAS
|
||||
#endif TP_PERF_MEAS
|
||||
*/
|
||||
|
||||
unsigned char argo_debug[128];
|
||||
|
||||
#define IFDEBUG(ascii) \
|
||||
if(argo_debug[ascii]) {
|
||||
#define ENDDEBUG ; }
|
||||
|
||||
#else /* ARGO_DEBUG */
|
||||
|
||||
/***********************************************
|
||||
* DEBUG OFF:
|
||||
**********************************************/
|
||||
|
||||
#ifndef STAR
|
||||
#define STAR *
|
||||
#endif /* STAR */
|
||||
#define IFDEBUG(ascii) //*beginning of comment*/STAR
|
||||
#define ENDDEBUG STAR/*end of comment*//
|
||||
|
||||
#endif /* ARGO_DEBUG */
|
||||
|
||||
/***********************************************
|
||||
* ASSERT
|
||||
**********************************************/
|
||||
#ifdef ARGO_DEBUG
|
||||
|
||||
#ifndef lint
|
||||
#define ASSERT(phrase) \
|
||||
if( !(phrase) ) printf("ASSERTION NOT VALID at line %d file %s\n",__LINE__,__FILE__)
|
||||
#else /* lint */
|
||||
#define ASSERT(phrase) /* phrase */
|
||||
#endif /* lint */
|
||||
|
||||
#else /* ARGO_DEBUG */
|
||||
|
||||
#define ASSERT(phrase) /* phrase */
|
||||
|
||||
#endif /* ARGO_DEBUG */
|
||||
|
||||
|
||||
/***********************************************
|
||||
* CLNP DEBUG OPTIONS
|
||||
**********************************************/
|
||||
#define D_INPUT '\1'
|
||||
/* clnp input */
|
||||
#define D_OUTPUT '\2'
|
||||
/* clnp output */
|
||||
#define D_ROUTE '\3'
|
||||
/* clnp routing */
|
||||
#define D_CTLINPUT '\4'
|
||||
/* clnp control input */
|
||||
#define D_CTLOUTPUT '\5'
|
||||
/* clnp control output */
|
||||
#define D_OPTIONS '\6'
|
||||
/* clnp options */
|
||||
#define D_IOCTL '\7'
|
||||
/* iso ioctls */
|
||||
#define D_ETHER '\10'
|
||||
/* clnp over ethernet */
|
||||
#define D_TOKEN '\11'
|
||||
/* clnp over token ring */
|
||||
#define D_ADCOM '\12'
|
||||
/* clnp over the adcom */
|
||||
#define D_ISO '\13'
|
||||
/* iso address family */
|
||||
#define D_FORWARD '\14'
|
||||
/* clnp forwarding */
|
||||
#define D_DUMPOUT '\15'
|
||||
/* dump clnp outgoing packets */
|
||||
#define D_DUMPIN '\16'
|
||||
/* dump clnp input packets */
|
||||
#define D_DISCARD '\17'
|
||||
/* debug clnp packet discard/er function */
|
||||
#define D_FRAG '\20'
|
||||
/* clnp fragmentation */
|
||||
#define D_REASS '\21'
|
||||
/* clnp reassembly */
|
||||
|
||||
char *clnp_iso_addrp();
|
||||
|
||||
/***********************************************
|
||||
* ESIS DEBUG OPTIONS
|
||||
**********************************************/
|
||||
#define D_ESISOUTPUT '\30'
|
||||
#define D_ESISINPUT '\31'
|
||||
#define D_SNPA '\32'
|
||||
|
||||
/***********************************************
|
||||
* ISIS DEBUG OPTIONS
|
||||
**********************************************/
|
||||
#define D_ISISOUTPUT '\40'
|
||||
#define D_ISISINPUT '\41'
|
||||
|
||||
/***********************************************
|
||||
* EON DEBUG OPTION
|
||||
**********************************************/
|
||||
#define D_EON '\57'
|
||||
|
||||
/***********************************************
|
||||
* CONS DEBUG OPTIONS
|
||||
**********************************************/
|
||||
|
||||
#define D_ECNWORK '\60'
|
||||
#define D_ECNOUT '\61'
|
||||
#define D_ECNFIN '\62'
|
||||
#define D_ECNDWN '\63'
|
||||
#define D_ECNUTIL '\64'
|
||||
|
||||
#define D_INCOMING '\70'
|
||||
#define D_CDATA '\71'
|
||||
#define D_CFIND '\72'
|
||||
#define D_CDUMP_REQ '\73'
|
||||
#define D_CADDR '\74'
|
||||
#define D_CCONS '\75'
|
||||
#define D_CCONN '\76'
|
||||
|
||||
|
||||
/***********************************************
|
||||
* TP DEBUG OPTIONS
|
||||
**********************************************/
|
||||
|
||||
#define D_SETPARAMS '\137'
|
||||
#define D_RTT '\140'
|
||||
|
||||
#define D_ACKRECV '\141'
|
||||
#define D_ACKSEND '\142'
|
||||
#define D_CONN '\143'
|
||||
#define D_CREDIT '\144'
|
||||
#define D_DATA '\145'
|
||||
#define D_DRIVER '\146'
|
||||
|
||||
#define D_EMIT '\147'
|
||||
#define D_ERROR_EMIT '\150'
|
||||
#define D_TPINPUT '\151'
|
||||
#define D_INDICATION '\152'
|
||||
#define D_CHKSUM '\153'
|
||||
|
||||
#define D_RENEG '\154'
|
||||
#define D_PERF_MEAS '\155'
|
||||
#define D_MBUF_MEAS '\156'
|
||||
#define D_RTC '\157'
|
||||
#define D_SB '\160'
|
||||
|
||||
#define D_DISASTER_CHECK '\161'
|
||||
#define D_REQUEST '\162'
|
||||
#define D_STASH '\163'
|
||||
#define D_NEWSOCK '\164'
|
||||
#define D_TIMER '\165'
|
||||
|
||||
#define D_TPIOCTL '\166'
|
||||
#define D_SIZE_CHECK '\167'
|
||||
#define D_2ER '\170'
|
||||
#define D_DISASTER_CHECK_W '\171'
|
||||
|
||||
#define D_XPD '\172'
|
||||
#define D_SYSCALL '\173'
|
||||
#define D_DROP '\174'
|
||||
#define D_ZDREF '\175'
|
||||
#define D_TPISO '\176'
|
||||
#define D_QUENCH '\177'
|
||||
|
||||
void dump_mbuf();
|
||||
|
||||
/***********************************************
|
||||
* New mbuf types for debugging w/ netstat -m
|
||||
* This messes up 4.4 malloc for now. need bigger
|
||||
* mbtypes array for now.
|
||||
**********************************************/
|
||||
#ifdef notdef
|
||||
|
||||
#define TPMT_DATA 0x21
|
||||
#define TPMT_RCVRTC 0x42
|
||||
#define TPMT_SNDRTC 0x41
|
||||
#define TPMT_TPHDR 0x22
|
||||
#define TPMT_IPHDR 0x32
|
||||
#define TPMT_SONAME 0x28
|
||||
#define TPMT_EOT 0x40
|
||||
#define TPMT_XPD 0x44
|
||||
#define TPMT_PCB 0x23
|
||||
#define TPMT_PERF 0x45
|
||||
|
||||
#else /* ARGO_DEBUG */
|
||||
|
||||
#define TPMT_DATA MT_DATA
|
||||
#define TPMT_RCVRTC MT_DATA
|
||||
#define TPMT_SNDRTC MT_DATA
|
||||
#define TPMT_IPHDR MT_HEADER
|
||||
#define TPMT_TPHDR MT_HEADER
|
||||
#define TPMT_SONAME MT_SONAME
|
||||
/* MT_EOT and MT_XPD are defined in tp_param.h */
|
||||
#define TPMT_XPD MT_OOBDATA
|
||||
#define TPMT_PCB MT_PCB
|
||||
#define TPMT_PERF MT_PCB
|
||||
|
||||
#endif /* ARGO_DEBUG */
|
||||
|
||||
#endif
|
||||
@@ -1,70 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnl.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnl.h,v 1.3 1994/08/21 06:14:12 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_CLNL_H_
|
||||
#define _NETISO_CLNL_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
struct clnl_protosw {
|
||||
int (*clnl_input)(); /* input routine */
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,469 +0,0 @@
|
||||
/*-
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp.h 8.2 (Berkeley) 4/16/94
|
||||
* $Id: clnp.h,v 1.4 1995/05/30 08:10:12 rgrimes Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_CLNP_H_
|
||||
#define _NETISO_CLNP_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp.h,v 1.4 1995/05/30 08:10:12 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp.h,v $ */
|
||||
|
||||
/* should be config option but cpp breaks with too many #defines */
|
||||
#define DECBIT
|
||||
|
||||
/*
|
||||
* Return true if the mbuf is a cluster mbuf
|
||||
*/
|
||||
#define IS_CLUSTER(m) ((m)->m_flags & M_EXT)
|
||||
|
||||
/*
|
||||
* Move the halfword into the two characters
|
||||
*/
|
||||
#define HTOC(msb, lsb, hword)\
|
||||
(msb) = (u_char)((hword) >> 8);\
|
||||
(lsb) = (u_char)((hword) & 0xff)
|
||||
/*
|
||||
* Move the two characters into the halfword
|
||||
*/
|
||||
#define CTOH(msb, lsb, hword)\
|
||||
(hword) = ((msb) << 8) | (lsb)
|
||||
|
||||
/*
|
||||
* Return true if the checksum has been set - ie. the checksum is
|
||||
* not zero
|
||||
*/
|
||||
#define CKSUM_REQUIRED(clnp)\
|
||||
(((clnp)->cnf_cksum_msb != 0) || ((clnp)->cnf_cksum_lsb != 0))
|
||||
|
||||
/*
|
||||
* Fixed part of clnp header
|
||||
*/
|
||||
struct clnp_fixed {
|
||||
u_char cnf_proto_id; /* network layer protocol identifier */
|
||||
u_char cnf_hdr_len; /* length indicator (octets) */
|
||||
u_char cnf_vers; /* version/protocol identifier extension */
|
||||
u_char cnf_ttl; /* lifetime (500 milliseconds) */
|
||||
u_char cnf_type; /* type code */
|
||||
/* Includes err_ok, more_segs, and seg_ok */
|
||||
u_char cnf_seglen_msb; /* pdu segment length (octets) high byte */
|
||||
u_char cnf_seglen_lsb; /* pdu segment length (octets) low byte */
|
||||
u_char cnf_cksum_msb; /* checksum high byte */
|
||||
u_char cnf_cksum_lsb; /* checksum low byte */
|
||||
};
|
||||
#define CNF_TYPE 0x1f
|
||||
#define CNF_ERR_OK 0x20
|
||||
#define CNF_MORE_SEGS 0x40
|
||||
#define CNF_SEG_OK 0x80
|
||||
|
||||
#define CLNP_CKSUM_OFF 0x07 /* offset of checksum */
|
||||
|
||||
#define clnl_fixed clnp_fixed
|
||||
|
||||
/*
|
||||
* Segmentation part of clnp header
|
||||
*/
|
||||
struct clnp_segment {
|
||||
u_short cng_id; /* data unit identifier */
|
||||
u_short cng_off; /* segment offset */
|
||||
u_short cng_tot_len; /* total length */
|
||||
};
|
||||
|
||||
/*
|
||||
* Clnp fragment reassembly structures:
|
||||
*
|
||||
* All packets undergoing reassembly are linked together in
|
||||
* clnp_fragl structures. Each clnp_fragl structure contains a
|
||||
* pointer to the original clnp packet header, as well as a
|
||||
* list of packet fragments. Each packet fragment
|
||||
* is headed by a clnp_frag structure. This structure contains the
|
||||
* offset of the first and last byte of the fragment, as well as
|
||||
* a pointer to the data (an mbuf chain) of the fragment.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* The clnp_frag structure is stored in an mbuf immediately preceding
|
||||
* the fragment data. Since there are words in this struct,
|
||||
* it must be word aligned.
|
||||
*
|
||||
* NOTE:
|
||||
* All the fragment code assumes that the entire clnp header is
|
||||
* contained in the first mbuf.
|
||||
*/
|
||||
struct clnp_frag {
|
||||
u_int cfr_first; /* offset of first byte of this frag */
|
||||
u_int cfr_last; /* offset of last byte of this frag */
|
||||
u_int cfr_bytes; /* bytes to shave to get to data */
|
||||
struct mbuf *cfr_data; /* ptr to data for this frag */
|
||||
struct clnp_frag *cfr_next; /* next fragment in list */
|
||||
};
|
||||
|
||||
struct clnp_fragl {
|
||||
struct iso_addr cfl_src; /* source of the pkt */
|
||||
struct iso_addr cfl_dst; /* destination of the pkt */
|
||||
u_short cfl_id; /* id of the pkt */
|
||||
u_char cfl_ttl; /* current ttl of pkt */
|
||||
u_short cfl_last; /* offset of last byte of packet */
|
||||
struct mbuf *cfl_orighdr; /* ptr to original header */
|
||||
struct clnp_frag *cfl_frags; /* linked list of fragments for pkt */
|
||||
struct clnp_fragl *cfl_next; /* next pkt being reassembled */
|
||||
};
|
||||
|
||||
/*
|
||||
* The following structure is used to index into an options section
|
||||
* of a clnp datagram. These values can be used without worry that
|
||||
* offset or length fields are invalid or too big, etc. That is,
|
||||
* the consistency of the options will be guaranteed before this
|
||||
* structure is filled in. Any pointer (field ending in p) is
|
||||
* actually the offset from the beginning of the mbuf the option
|
||||
* is contained in. A value of NULL for any pointer
|
||||
* means that the option is not present. The length any option
|
||||
* does not include the option code or option length fields.
|
||||
*/
|
||||
struct clnp_optidx {
|
||||
u_short cni_securep; /* ptr to beginning of security option */
|
||||
char cni_secure_len; /* length of entire security option */
|
||||
|
||||
u_short cni_srcrt_s; /* offset of start of src rt option */
|
||||
u_short cni_srcrt_len; /* length of entire src rt option */
|
||||
|
||||
u_short cni_recrtp; /* ptr to beginning of recrt option */
|
||||
char cni_recrt_len; /* length of entire recrt option */
|
||||
|
||||
char cni_priorp; /* ptr to priority option */
|
||||
|
||||
u_short cni_qos_formatp; /* ptr to format of qos option */
|
||||
char cni_qos_len; /* length of entire qos option */
|
||||
|
||||
u_char cni_er_reason; /* reason from ER pdu option */
|
||||
|
||||
/* ESIS options */
|
||||
|
||||
u_short cni_esct; /* value from ISH ESCT option */
|
||||
|
||||
u_short cni_netmaskp; /* ptr to beginning of netmask option */
|
||||
char cni_netmask_len; /* length of entire netmask option */
|
||||
|
||||
u_short cni_snpamaskp; /* ptr to beginning of snpamask option */
|
||||
char cni_snpamask_len; /* length of entire snpamask option */
|
||||
|
||||
};
|
||||
|
||||
#define ER_INVALREAS 0xff /* code for invalid ER pdu discard reason */
|
||||
|
||||
/* given an mbuf and addr of option, return offset from data of mbuf */
|
||||
#define CLNP_OPTTOOFF(m, opt)\
|
||||
((u_short) (opt - mtod(m, caddr_t)))
|
||||
|
||||
/* given an mbuf and offset of option, return address of option */
|
||||
#define CLNP_OFFTOOPT(m, off)\
|
||||
((caddr_t) (mtod(m, caddr_t) + off))
|
||||
|
||||
/* return true iff src route is valid */
|
||||
#define CLNPSRCRT_VALID(oidx)\
|
||||
((oidx) && (oidx->cni_srcrt_s))
|
||||
|
||||
/* return the offset field of the src rt */
|
||||
#define CLNPSRCRT_OFF(oidx, options)\
|
||||
(*((u_char *)(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s) + 1)))
|
||||
|
||||
/* return the type field of the src rt */
|
||||
#define CLNPSRCRT_TYPE(oidx, options)\
|
||||
((u_char)(*(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s))))
|
||||
|
||||
/* return the length of the current address */
|
||||
#define CLNPSRCRT_CLEN(oidx, options)\
|
||||
((u_char)(*(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s) + CLNPSRCRT_OFF(oidx, options) - 1)))
|
||||
|
||||
/* return the address of the current address */
|
||||
#define CLNPSRCRT_CADDR(oidx, options)\
|
||||
((caddr_t)(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s) + CLNPSRCRT_OFF(oidx, options)))
|
||||
|
||||
/*
|
||||
* return true if the src route has run out of routes
|
||||
* this is true if the offset of next route is greater than the end of the rt
|
||||
*/
|
||||
#define CLNPSRCRT_TERM(oidx, options)\
|
||||
(CLNPSRCRT_OFF(oidx, options) > oidx->cni_srcrt_len)
|
||||
|
||||
/*
|
||||
* Options a user can set/get
|
||||
*/
|
||||
#define CLNPOPT_FLAGS 0x01 /* flags: seg permitted, no er xmit, etc */
|
||||
#define CLNPOPT_OPTS 0x02 /* datagram options */
|
||||
|
||||
/*
|
||||
* Values for particular datagram options
|
||||
*/
|
||||
#define CLNPOVAL_PAD 0xcc /* padding */
|
||||
#define CLNPOVAL_SECURE 0xc5 /* security */
|
||||
#define CLNPOVAL_SRCRT 0xc8 /* source routing */
|
||||
#define CLNPOVAL_RECRT 0xcb /* record route */
|
||||
#define CLNPOVAL_QOS 0xc3 /* quality of service */
|
||||
#define CLNPOVAL_PRIOR 0xcd /* priority */
|
||||
#define CLNPOVAL_ERREAS 0xc1 /* ER PDU ONLY: reason for discard */
|
||||
|
||||
#define CLNPOVAL_SRCSPEC 0x40 /* source address specific */
|
||||
#define CLNPOVAL_DSTSPEC 0x80 /* destination address specific */
|
||||
#define CLNPOVAL_GLOBAL 0xc0 /* globally unique */
|
||||
|
||||
/* Globally Unique QOS */
|
||||
#define CLNPOVAL_SEQUENCING 0x10 /* sequencing preferred */
|
||||
#define CLNPOVAL_CONGESTED 0x08 /* congestion experienced */
|
||||
#define CLNPOVAL_LOWDELAY 0x04 /* low transit delay */
|
||||
|
||||
#define CLNPOVAL_PARTRT 0x00 /* partial source routing */
|
||||
#define CLNPOVAL_COMPRT 0x01 /* complete source routing */
|
||||
|
||||
/*
|
||||
* Clnp flags used in a control block flags field.
|
||||
* NOTE: these must be out of the range of bits defined in ../net/raw_cb.h
|
||||
*/
|
||||
#define CLNP_NO_SEG 0x010 /* segmentation not permitted */
|
||||
#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 /* 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_ECHOR)
|
||||
|
||||
/*
|
||||
* Constants used by clnp
|
||||
*/
|
||||
#define CLNP_HDR_MIN (sizeof (struct clnp_fixed))
|
||||
#define CLNP_HDR_MAX (254)
|
||||
#define CLNP_TTL_UNITS 2 /* 500 milliseconds */
|
||||
#define CLNP_TTL 15*CLNP_TTL_UNITS /* time to live (seconds) */
|
||||
#define ISO8473_V1 0x01
|
||||
|
||||
/*
|
||||
* Clnp packet types
|
||||
* In order to test raw clnp and tp/clnp simultaneously, a third type of
|
||||
* packet has been defined: CLNP_RAW. This is done so that the input
|
||||
* routine can switch to the correct input routine (rclnp_input or
|
||||
* tpclnp_input) based on the type field. If clnp had a higher level protocol
|
||||
* field, this would not be necessary.
|
||||
*/
|
||||
#define CLNP_DT 0x1C /* normal data */
|
||||
#define CLNP_ER 0x01 /* error report */
|
||||
#define CLNP_RAW 0x1D /* debug only */
|
||||
#define CLNP_EC 0x1E /* echo packet */
|
||||
#define CLNP_ECR 0x1F /* echo reply */
|
||||
|
||||
/*
|
||||
* ER pdu error codes
|
||||
*/
|
||||
#define GEN_NOREAS 0x00 /* reason not specified */
|
||||
#define GEN_PROTOERR 0x01 /* protocol procedure error */
|
||||
#define GEN_BADCSUM 0x02 /* incorrect checksum */
|
||||
#define GEN_CONGEST 0x03 /* pdu discarded due to congestion */
|
||||
#define GEN_HDRSYNTAX 0x04 /* header syntax error */
|
||||
#define GEN_SEGNEEDED 0x05 /* segmentation needed, but not permitted */
|
||||
#define GEN_INCOMPLETE 0x06 /* incomplete pdu received */
|
||||
#define GEN_DUPOPT 0x07 /* duplicate option */
|
||||
|
||||
/* address errors */
|
||||
#define ADDR_DESTUNREACH 0x80 /* destination address unreachable */
|
||||
#define ADDR_DESTUNKNOWN 0x81 /* destination address unknown */
|
||||
|
||||
/* source routing */
|
||||
#define SRCRT_UNSPECERR 0x90 /* unspecified src rt error */
|
||||
#define SRCRT_SYNTAX 0x91 /* syntax error in src rt field */
|
||||
#define SRCRT_UNKNOWNADDR 0x92 /* unknown addr in src rt field */
|
||||
#define SRCRT_BADPATH 0x93 /* path not acceptable */
|
||||
|
||||
/* lifetime */
|
||||
#define TTL_EXPTRANSIT 0xa0 /* lifetime expired during transit */
|
||||
#define TTL_EXPREASS 0xa1 /* lifetime expired during reassembly */
|
||||
|
||||
/* pdu discarded */
|
||||
#define DISC_UNSUPPOPT 0xb0 /* unsupported option not specified? */
|
||||
#define DISC_UNSUPPVERS 0xb1 /* unsupported protocol version */
|
||||
#define DISC_UNSUPPSECURE 0xb2 /* unsupported security option */
|
||||
#define DISC_UNSUPPSRCRT 0xb3 /* unsupported src rt option */
|
||||
#define DISC_UNSUPPRECRT 0xb4 /* unsupported rec rt option */
|
||||
|
||||
/* reassembly */
|
||||
#define REASS_INTERFERE 0xc0 /* reassembly interference */
|
||||
#define CLNP_ERRORS 22
|
||||
|
||||
|
||||
#ifdef KERNEL
|
||||
int clnp_er_index();
|
||||
#endif
|
||||
|
||||
#ifdef CLNP_ER_CODES
|
||||
u_char clnp_er_codes[CLNP_ERRORS] = {
|
||||
GEN_NOREAS, GEN_PROTOERR, GEN_BADCSUM, GEN_CONGEST,
|
||||
GEN_HDRSYNTAX, GEN_SEGNEEDED, GEN_INCOMPLETE, GEN_DUPOPT,
|
||||
ADDR_DESTUNREACH, ADDR_DESTUNKNOWN,
|
||||
SRCRT_UNSPECERR, SRCRT_SYNTAX, SRCRT_UNKNOWNADDR, SRCRT_BADPATH,
|
||||
TTL_EXPTRANSIT, TTL_EXPREASS,
|
||||
DISC_UNSUPPOPT, DISC_UNSUPPVERS, DISC_UNSUPPSECURE,
|
||||
DISC_UNSUPPSRCRT, DISC_UNSUPPRECRT, REASS_INTERFERE };
|
||||
#endif
|
||||
|
||||
#ifdef TROLL
|
||||
|
||||
#define TR_DUPEND 0x01 /* duplicate end of fragment */
|
||||
#define TR_DUPPKT 0x02 /* duplicate entire packet */
|
||||
#define TR_DROPPKT 0x04 /* drop packet on output */
|
||||
#define TR_TRIM 0x08 /* trim bytes from packet */
|
||||
#define TR_CHANGE 0x10 /* change bytes in packet */
|
||||
#define TR_MTU 0x20 /* delta to change device mtu */
|
||||
#define TR_CHUCK 0x40 /* drop packet in rclnp_input */
|
||||
#define TR_BLAST 0x80 /* force rclnp_output to blast many packet */
|
||||
#define TR_RAWLOOP 0x100 /* make if_loop call clnpintr directly */
|
||||
struct troll {
|
||||
int tr_ops; /* operations to perform */
|
||||
float tr_dup_size; /* % to duplicate */
|
||||
float tr_dup_freq; /* frequency to duplicate packets */
|
||||
float tr_drop_freq; /* frequence to drop packets */
|
||||
int tr_mtu_adj; /* delta to adjust if mtu */
|
||||
int tr_blast_cnt; /* # of pkts to blast out */
|
||||
};
|
||||
|
||||
#define SN_OUTPUT(clcp, m)\
|
||||
troll_output(clcp->clc_ifp, m, clcp->clc_firsthop, clcp->clc_rt)
|
||||
|
||||
#define SN_MTU(ifp, rt) (((rt && rt->rt_rmx.rmx_mtu) ?\
|
||||
rt->rt_rmx.rmx_mtu : clnp_badmtu(ifp, rt, __LINE__, __FILE__))\
|
||||
- trollctl.tr_mtu_adj)
|
||||
|
||||
#ifdef KERNEL
|
||||
extern float troll_random;
|
||||
#endif
|
||||
|
||||
#else /* NO TROLL */
|
||||
|
||||
#define SN_OUTPUT(clcp, m)\
|
||||
(*clcp->clc_ifp->if_output)(clcp->clc_ifp, m, clcp->clc_firsthop, clcp->clc_rt)
|
||||
|
||||
#define SN_MTU(ifp, rt) (((rt && rt->rt_rmx.rmx_mtu) ?\
|
||||
rt->rt_rmx.rmx_mtu : clnp_badmtu(ifp, rt, __LINE__, __FILE__)))
|
||||
|
||||
#endif /* TROLL */
|
||||
|
||||
/*
|
||||
* Macro to remove an address from a clnp header
|
||||
*/
|
||||
#define CLNP_EXTRACT_ADDR(isoa, hoff, hend)\
|
||||
{\
|
||||
isoa.isoa_len = (u_char)*hoff;\
|
||||
if ((((++hoff) + isoa.isoa_len) > hend) ||\
|
||||
(isoa.isoa_len > 20) || (isoa.isoa_len == 0)) {\
|
||||
hoff = (caddr_t)0;\
|
||||
} else {\
|
||||
(void) bcopy(hoff, (caddr_t)isoa.isoa_genaddr, isoa.isoa_len);\
|
||||
hoff += isoa.isoa_len;\
|
||||
}\
|
||||
}
|
||||
|
||||
/*
|
||||
* Macro to insert an address into a clnp header
|
||||
*/
|
||||
#define CLNP_INSERT_ADDR(hoff, isoa)\
|
||||
*hoff++ = (isoa).isoa_len;\
|
||||
(void) bcopy((caddr_t)((isoa).isoa_genaddr), hoff, (isoa).isoa_len);\
|
||||
hoff += (isoa).isoa_len;
|
||||
|
||||
/*
|
||||
* Clnp hdr cache. Whenever a clnp packet is sent, a copy of the
|
||||
* header is made and kept in this cache. In addition to a copy of
|
||||
* the cached clnp hdr, the cache contains
|
||||
* information necessary to determine whether the new packet
|
||||
* to send requires a new header to be built.
|
||||
*/
|
||||
struct clnp_cache {
|
||||
/* these fields are used to check the validity of the cache */
|
||||
struct iso_addr clc_dst; /* destination of packet */
|
||||
struct mbuf *clc_options; /* ptr to options mbuf */
|
||||
int clc_flags; /* flags passed to clnp_output */
|
||||
|
||||
/* these fields are state that clnp_output requires to finish the pkt */
|
||||
int clc_segoff; /* offset of seg part of header */
|
||||
struct rtentry *clc_rt; /* ptr to rtentry (points into
|
||||
the route structure) */
|
||||
struct sockaddr *clc_firsthop; /* first hop of packet */
|
||||
struct ifnet *clc_ifp; /* ptr to interface structure */
|
||||
struct iso_ifaddr *clc_ifa; /* ptr to interface address */
|
||||
struct mbuf *clc_hdr; /* cached pkt hdr (finally)! */
|
||||
};
|
||||
|
||||
#ifndef satosiso
|
||||
#define satosiso(sa)\
|
||||
((struct sockaddr_iso *)(sa))
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL
|
||||
caddr_t clnp_insert_addr();
|
||||
struct iso_addr *clnp_srcaddr();
|
||||
struct mbuf *clnp_reass();
|
||||
#ifdef TROLL
|
||||
struct troll trollctl;
|
||||
#endif /* TROLL */
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif
|
||||
@@ -1,260 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp_debug.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnp_debug.c,v 1.3 1995/05/30 08:10:14 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp_debug.c,v 1.3 1995/05/30 08:10:14 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp_debug.c,v $ */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/clnp_stat.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
|
||||
#ifdef ARGO_DEBUG
|
||||
|
||||
#ifdef TESTDEBUG
|
||||
#ifdef notdef
|
||||
struct addr_37 u_37 = {
|
||||
{0x00, 0x02, 0x00, 0x10, 0x20, 0x30, 0x35},
|
||||
{0x01, 0x02, 0x03, 0x04, 0x50, 0x60, 0x70, 0x80, 0x90}
|
||||
};
|
||||
struct addr_osinet u_osinet = {
|
||||
{0x00, 0x04},
|
||||
{0x00, 0x02, 0x00, 0x01, 0x23, 0x42, 0x78, 0x20, 0x01, 0x05, 0x00}
|
||||
};
|
||||
#endif /* notdef */
|
||||
struct addr_rfc986 u_rfc986 = {
|
||||
{0x00, 0x06},
|
||||
{0x01, 0xc0, 0x0c, 0x0c, 0xab, 0x11}
|
||||
};
|
||||
struct addr_rfc986 u_bad = {
|
||||
{0x00, 0x01},
|
||||
{0x01, 0xc0, 0x0c, 0x0c, 0xab, 0x11}
|
||||
};
|
||||
#include <stdio.h>
|
||||
main()
|
||||
{
|
||||
struct iso_addr a;
|
||||
|
||||
a.isoa_afi = AFI_37;
|
||||
a.isoa_u.addr_37 = u_37;
|
||||
a.isoa_len = 17;
|
||||
printf("type 37: %s\n", clnp_iso_addrp(&a));
|
||||
|
||||
a.isoa_afi = AFI_OSINET;
|
||||
a.isoa_u.addr_osinet = u_osinet;
|
||||
a.isoa_len = 14;
|
||||
printf("type osinet: %s\n", clnp_iso_addrp(&a));
|
||||
|
||||
a.isoa_afi = AFI_RFC986;
|
||||
a.isoa_u.addr_rfc986 = u_rfc986;
|
||||
a.isoa_len = 9;
|
||||
printf("type rfc986: %s\n", clnp_iso_addrp(&a));
|
||||
|
||||
a.isoa_afi = 12;
|
||||
a.isoa_u.addr_rfc986 = u_rfc986;
|
||||
a.isoa_len = 9;
|
||||
printf("type bad afi: %s\n", clnp_iso_addrp(&a));
|
||||
|
||||
a.isoa_afi = AFI_RFC986;
|
||||
a.isoa_u.addr_rfc986 = u_bad;
|
||||
a.isoa_len = 9;
|
||||
printf("type bad idi: %s\n", clnp_iso_addrp(&a));
|
||||
}
|
||||
#endif /* TESTDEBUG */
|
||||
|
||||
unsigned int clnp_debug;
|
||||
|
||||
/*
|
||||
* Print buffer in hex, return addr of where we left off.
|
||||
* Do not null terminate.
|
||||
*/
|
||||
char *
|
||||
clnp_hexp(src, len, where)
|
||||
char *src; /* src of data to print */
|
||||
int len; /* lengthof src */
|
||||
char *where; /* where to put data */
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
register int j = ((u_char *)src)[i];
|
||||
*where++ = hex2ascii[j >> 4];
|
||||
*where++ = hex2ascii[j & 0x0f];
|
||||
}
|
||||
return where;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a ptr to a human readable form of an iso addr
|
||||
*/
|
||||
static char iso_addr_b[50];
|
||||
#define DELIM '.';
|
||||
|
||||
char *
|
||||
clnp_iso_addrp(isoa)
|
||||
struct iso_addr *isoa;
|
||||
{
|
||||
char *cp;
|
||||
|
||||
/* print length */
|
||||
sprintf(iso_addr_b, "[%d] ", isoa->isoa_len);
|
||||
|
||||
/* set cp to end of what we have */
|
||||
cp = iso_addr_b;
|
||||
while (*cp)
|
||||
cp++;
|
||||
|
||||
/* print afi */
|
||||
cp = clnp_hexp(isoa->isoa_genaddr, (int)isoa->isoa_len, cp);
|
||||
#ifdef notdef
|
||||
*cp++ = DELIM;
|
||||
|
||||
/* print type specific part */
|
||||
switch(isoa->isoa_afi) {
|
||||
case AFI_37:
|
||||
cp = clnp_hexp(isoa->t37_idi, ADDR37_IDI_LEN, cp);
|
||||
*cp++ = DELIM;
|
||||
cp = clnp_hexp(isoa->t37_dsp, ADDR37_DSP_LEN, cp);
|
||||
break;
|
||||
|
||||
/* case AFI_OSINET:*/
|
||||
case AFI_RFC986: {
|
||||
u_short idi;
|
||||
|
||||
/* osinet and rfc986 have idi in the same place */
|
||||
/* print idi */
|
||||
cp = clnp_hexp(isoa->rfc986_idi, ADDROSINET_IDI_LEN, cp);
|
||||
*cp++ = DELIM;
|
||||
CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi);
|
||||
|
||||
if (idi == IDI_OSINET) {
|
||||
struct ovl_osinet *oosi = (struct ovl_osinet *)isoa;
|
||||
cp = clnp_hexp(oosi->oosi_orgid, OVLOSINET_ORGID_LEN, cp);
|
||||
*cp++ = DELIM;
|
||||
cp = clnp_hexp(oosi->oosi_snetid, OVLOSINET_SNETID_LEN, cp);
|
||||
*cp++ = DELIM;
|
||||
cp = clnp_hexp(oosi->oosi_snpa, OVLOSINET_SNPA_LEN, cp);
|
||||
*cp++ = DELIM;
|
||||
cp = clnp_hexp(oosi->oosi_nsap, OVLOSINET_NSAP_LEN, cp);
|
||||
} else if (idi == IDI_RFC986) {
|
||||
struct ovl_rfc986 *o986 = (struct ovl_rfc986 *)isoa;
|
||||
cp = clnp_hexp(&o986->o986_vers, 1, cp);
|
||||
*cp++ = DELIM;
|
||||
#ifdef vax
|
||||
sprintf(cp, "%d.%d.%d.%d.%d",
|
||||
o986->o986_inetaddr[0] & 0xff,
|
||||
o986->o986_inetaddr[1] & 0xff,
|
||||
o986->o986_inetaddr[2] & 0xff,
|
||||
o986->o986_inetaddr[3] & 0xff,
|
||||
o986->o986_upid & 0xff);
|
||||
return(iso_addr_b);
|
||||
#else
|
||||
cp = clnp_hexp(&o986->o986_inetaddr[0], 1, cp);
|
||||
*cp++ = DELIM;
|
||||
cp = clnp_hexp(&o986->o986_inetaddr[1], 1, cp);
|
||||
*cp++ = DELIM;
|
||||
cp = clnp_hexp(&o986->o986_inetaddr[2], 1, cp);
|
||||
*cp++ = DELIM;
|
||||
cp = clnp_hexp(&o986->o986_inetaddr[3], 1, cp);
|
||||
*cp++ = DELIM;
|
||||
cp = clnp_hexp(&o986->o986_upid, 1, cp);
|
||||
#endif /* vax */
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
default:
|
||||
*cp++ = '?';
|
||||
break;
|
||||
}
|
||||
#endif /* notdef */
|
||||
*cp = (char)0;
|
||||
|
||||
return(iso_addr_b);
|
||||
}
|
||||
|
||||
char *
|
||||
clnp_saddr_isop(s)
|
||||
register struct sockaddr_iso *s;
|
||||
{
|
||||
register char *cp = clnp_iso_addrp(&s->siso_addr);
|
||||
|
||||
while (*cp) cp++;
|
||||
*cp++ = '(';
|
||||
cp = clnp_hexp(TSEL(s), (int)s->siso_tlen, cp);
|
||||
*cp++ = ')';
|
||||
*cp++ = 0;
|
||||
return (iso_addr_b);
|
||||
}
|
||||
|
||||
#endif /* ARGO_DEBUG */
|
||||
@@ -1,377 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp_er.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnp_er.c,v 1.3 1994/11/15 14:26:10 bde Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp_er.c,v 1.3 1994/11/15 14:26:10 bde Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp_er.c,v $ */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/iso_pcb.h>
|
||||
#define CLNP_ER_CODES
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/clnp_stat.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
|
||||
static struct clnp_fixed er_template = {
|
||||
ISO8473_CLNP, /* network identifier */
|
||||
0, /* length */
|
||||
ISO8473_V1, /* version */
|
||||
CLNP_TTL, /* ttl */
|
||||
CLNP_ER, /* type */
|
||||
0, /* segment length */
|
||||
0 /* checksum */
|
||||
};
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_er_input
|
||||
*
|
||||
* PURPOSE: Process an ER pdu.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
clnp_er_input(m, src, reason)
|
||||
struct mbuf *m; /* ptr to packet itself */
|
||||
struct iso_addr *src; /* ptr to src of er */
|
||||
u_char reason; /* reason code of er */
|
||||
{
|
||||
int cmd = -1;
|
||||
extern u_char clnp_protox[];
|
||||
|
||||
IFDEBUG(D_CTLINPUT)
|
||||
printf("clnp_er_input: m x%x, src %s, reason x%x\n", m,
|
||||
clnp_iso_addrp(src), reason);
|
||||
ENDDEBUG
|
||||
|
||||
INCSTAT(cns_er_inhist[clnp_er_index(reason)]);
|
||||
switch (reason) {
|
||||
case GEN_NOREAS:
|
||||
case GEN_PROTOERR:
|
||||
break;
|
||||
case GEN_BADCSUM:
|
||||
cmd = PRC_PARAMPROB;
|
||||
break;
|
||||
case GEN_CONGEST:
|
||||
cmd = PRC_QUENCH;
|
||||
break;
|
||||
case GEN_HDRSYNTAX:
|
||||
cmd = PRC_PARAMPROB;
|
||||
break;
|
||||
case GEN_SEGNEEDED:
|
||||
cmd = PRC_MSGSIZE;
|
||||
break;
|
||||
case GEN_INCOMPLETE:
|
||||
cmd = PRC_PARAMPROB;
|
||||
break;
|
||||
case GEN_DUPOPT:
|
||||
cmd = PRC_PARAMPROB;
|
||||
break;
|
||||
case ADDR_DESTUNREACH:
|
||||
cmd = PRC_UNREACH_HOST;
|
||||
break;
|
||||
case ADDR_DESTUNKNOWN:
|
||||
cmd = PRC_UNREACH_PROTOCOL;
|
||||
break;
|
||||
case SRCRT_UNSPECERR:
|
||||
case SRCRT_SYNTAX:
|
||||
case SRCRT_UNKNOWNADDR:
|
||||
case SRCRT_BADPATH:
|
||||
cmd = PRC_UNREACH_SRCFAIL;
|
||||
break;
|
||||
case TTL_EXPTRANSIT:
|
||||
cmd = PRC_TIMXCEED_INTRANS;
|
||||
break;
|
||||
case TTL_EXPREASS:
|
||||
cmd = PRC_TIMXCEED_REASS;
|
||||
break;
|
||||
case DISC_UNSUPPOPT:
|
||||
case DISC_UNSUPPVERS:
|
||||
case DISC_UNSUPPSECURE:
|
||||
case DISC_UNSUPPSRCRT:
|
||||
case DISC_UNSUPPRECRT:
|
||||
cmd = PRC_PARAMPROB;
|
||||
break;
|
||||
case REASS_INTERFERE:
|
||||
cmd = PRC_TIMXCEED_REASS;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* tpclnp_ctlinput1 is called directly so that we don't
|
||||
* have to build an iso_sockaddr out of src.
|
||||
*/
|
||||
if (cmd >= 0)
|
||||
tpclnp_ctlinput1(cmd, src);
|
||||
|
||||
m_freem(m);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_discard
|
||||
*
|
||||
* PURPOSE: Discard a clnp datagram
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*
|
||||
* SIDE EFFECTS: Will emit an ER pdu if possible
|
||||
*
|
||||
* NOTES: This code assumes that we have previously tried to pull
|
||||
* up the header of the datagram into one mbuf.
|
||||
*/
|
||||
clnp_discard(m, reason)
|
||||
struct mbuf *m; /* header of packet to discard */
|
||||
char reason; /* reason for discard */
|
||||
{
|
||||
IFDEBUG(D_DISCARD)
|
||||
printf("clnp_discard: m x%x, reason x%x\n", m, reason);
|
||||
ENDDEBUG
|
||||
|
||||
if (m != NULL) {
|
||||
if (m->m_len >= sizeof(struct clnp_fixed)) {
|
||||
register struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
|
||||
|
||||
if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
|
||||
(clnp->cnf_type & CNF_ERR_OK)) {
|
||||
clnp_emit_er(m, reason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_freem(m);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_emit_er
|
||||
*
|
||||
* PURPOSE: Send an ER pdu.
|
||||
* The src of the of the ER pdu is the host that is sending
|
||||
* the ER (ie. us), *not* the original destination of the
|
||||
* packet.
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: Takes responsibility for freeing mbuf passed
|
||||
* This function may be called with a packet that
|
||||
* was created by us; in this case, do not send
|
||||
* an ER.
|
||||
*/
|
||||
clnp_emit_er(m, reason)
|
||||
struct mbuf *m; /* header of packet to discard */
|
||||
char reason; /* reason for discard */
|
||||
{
|
||||
register struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
|
||||
register struct clnp_fixed *er;
|
||||
struct route_iso route;
|
||||
struct ifnet *ifp;
|
||||
struct sockaddr *first_hop;
|
||||
struct iso_addr src, dst, *our_addr;
|
||||
caddr_t hoff, hend;
|
||||
int total_len; /* total len of dg */
|
||||
struct mbuf *m0; /* contains er pdu hdr */
|
||||
struct iso_ifaddr *ia = 0;
|
||||
|
||||
IFDEBUG(D_DISCARD)
|
||||
printf("clnp_emit_er: m x%x, hdr len %d\n", m, clnp->cnf_hdr_len);
|
||||
ENDDEBUG
|
||||
|
||||
bzero((caddr_t)&route, sizeof(route));
|
||||
|
||||
/*
|
||||
* If header length is incorrect, or entire header is not contained
|
||||
* in this mbuf, we punt
|
||||
*/
|
||||
if ((clnp->cnf_hdr_len < CLNP_HDR_MIN) ||
|
||||
(clnp->cnf_hdr_len > CLNP_HDR_MAX) ||
|
||||
(clnp->cnf_hdr_len > m->m_len))
|
||||
goto bad;
|
||||
|
||||
/* extract src, dest address */
|
||||
hend = (caddr_t)clnp + clnp->cnf_hdr_len;
|
||||
hoff = (caddr_t)clnp + sizeof(struct clnp_fixed);
|
||||
CLNP_EXTRACT_ADDR(dst, hoff, hend);
|
||||
if (hoff == (caddr_t)0) {
|
||||
goto bad;
|
||||
}
|
||||
CLNP_EXTRACT_ADDR(src, hoff, hend);
|
||||
if (hoff == (caddr_t)0) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not send ER if we generated the packet.
|
||||
*/
|
||||
if (clnp_ours(&src))
|
||||
goto bad;
|
||||
|
||||
/*
|
||||
* Trim mbuf to hold only the header.
|
||||
* This mbuf will be the 'data' of the er pdu
|
||||
*/
|
||||
if (m->m_next != NULL) {
|
||||
m_freem(m->m_next);
|
||||
m->m_next = NULL;
|
||||
}
|
||||
|
||||
if (m->m_len > clnp->cnf_hdr_len)
|
||||
m_adj(m, (int)-(m->m_len - (int)clnp->cnf_hdr_len));
|
||||
|
||||
/* route er pdu: note we send pkt to src of original packet */
|
||||
if (clnp_route(&src, &route, /* flags */0, &first_hop, &ia) != 0)
|
||||
goto bad;
|
||||
|
||||
/* compute our address based upon firsthop/ifp */
|
||||
if (ia)
|
||||
our_addr = &ia->ia_addr.siso_addr;
|
||||
else
|
||||
goto bad;
|
||||
ifp = ia->ia_ifp;
|
||||
|
||||
IFDEBUG(D_DISCARD)
|
||||
printf("clnp_emit_er: to %s", clnp_iso_addrp(&src));
|
||||
printf(" from %s\n", clnp_iso_addrp(our_addr));
|
||||
ENDDEBUG
|
||||
|
||||
IFDEBUG(D_DISCARD)
|
||||
printf("clnp_emit_er: packet routed to %s\n",
|
||||
clnp_iso_addrp(&((struct sockaddr_iso *)first_hop)->siso_addr));
|
||||
ENDDEBUG
|
||||
|
||||
/* allocate mbuf for er pdu header: punt on no space */
|
||||
MGET(m0, M_DONTWAIT, MT_HEADER);
|
||||
if (m0 == 0)
|
||||
goto bad;
|
||||
|
||||
m0->m_next = m;
|
||||
er = mtod(m0, struct clnp_fixed *);
|
||||
*er = er_template;
|
||||
|
||||
/* setup src/dst on er pdu */
|
||||
/* NOTE REVERSAL OF SRC/DST */
|
||||
hoff = (caddr_t)er + sizeof(struct clnp_fixed);
|
||||
CLNP_INSERT_ADDR(hoff, src);
|
||||
CLNP_INSERT_ADDR(hoff, *our_addr);
|
||||
|
||||
/*
|
||||
* TODO: if complete src rt was specified, then reverse path, and
|
||||
* copy into er as option.
|
||||
*/
|
||||
|
||||
/* add er option */
|
||||
*hoff++ = CLNPOVAL_ERREAS; /* code */
|
||||
*hoff++ = 2; /* length */
|
||||
*hoff++ = reason; /* discard reason */
|
||||
*hoff++ = 0; /* error localization = not specified */
|
||||
|
||||
/* set length */
|
||||
er->cnf_hdr_len = m0->m_len = (u_char)(hoff - (caddr_t)er);
|
||||
total_len = m0->m_len + m->m_len;
|
||||
HTOC(er->cnf_seglen_msb, er->cnf_seglen_lsb, total_len);
|
||||
|
||||
/* compute checksum (on header only) */
|
||||
iso_gen_csum(m0, CLNP_CKSUM_OFF, (int)er->cnf_hdr_len);
|
||||
|
||||
/* trim packet if too large for interface */
|
||||
if (total_len > ifp->if_mtu)
|
||||
m_adj(m0, -(total_len - ifp->if_mtu));
|
||||
|
||||
/* send packet */
|
||||
INCSTAT(cns_er_outhist[clnp_er_index(reason)]);
|
||||
(void) (*ifp->if_output)(ifp, m0, first_hop, route.ro_rt);
|
||||
goto done;
|
||||
|
||||
bad:
|
||||
m_freem(m);
|
||||
|
||||
done:
|
||||
/* free route if it is a temp */
|
||||
if (route.ro_rt != NULL)
|
||||
RTFREE(route.ro_rt);
|
||||
}
|
||||
|
||||
clnp_er_index(p)
|
||||
u_char p;
|
||||
{
|
||||
register u_char *cp = clnp_er_codes + CLNP_ERRORS;
|
||||
while (cp > clnp_er_codes) {
|
||||
cp--;
|
||||
if (*cp == p)
|
||||
return (cp - clnp_er_codes);
|
||||
}
|
||||
return (CLNP_ERRORS + 1);
|
||||
}
|
||||
@@ -1,860 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp_frag.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnp_frag.c,v 1.2 1994/08/02 07:49:37 davidg Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp_frag.c,v 1.2 1994/08/02 07:49:37 davidg Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp_frag.c,v $ */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/clnp_stat.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
|
||||
/* all fragments are hung off this list */
|
||||
struct clnp_fragl *clnp_frags = NULL;
|
||||
|
||||
struct mbuf *clnp_comp_pdu();
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_fragment
|
||||
*
|
||||
* PURPOSE: Fragment a datagram, and send the itty bitty pieces
|
||||
* out over an interface.
|
||||
*
|
||||
* RETURNS: success - 0
|
||||
* failure - unix error code
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: If there is an error sending the packet, clnp_discard
|
||||
* is called to discard the packet and send an ER. If
|
||||
* clnp_fragment was called from clnp_output, then
|
||||
* we generated the packet, and should not send an
|
||||
* ER -- clnp_emit_er will check for this. Otherwise,
|
||||
* the packet was fragmented during forwarding. In this
|
||||
* case, we ought to send an ER back.
|
||||
*/
|
||||
clnp_fragment(ifp, m, first_hop, total_len, segoff, flags, rt)
|
||||
struct ifnet *ifp; /* ptr to outgoing interface */
|
||||
struct mbuf *m; /* ptr to packet */
|
||||
struct sockaddr *first_hop; /* ptr to first hop */
|
||||
int total_len; /* length of datagram */
|
||||
int segoff; /* offset of segpart in hdr */
|
||||
int flags; /* flags passed to clnp_output */
|
||||
struct rtentry *rt; /* route if direct ether */
|
||||
{
|
||||
struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
|
||||
int hdr_len = (int)clnp->cnf_hdr_len;
|
||||
int frag_size = (SN_MTU(ifp, rt) - hdr_len) & ~7;
|
||||
|
||||
total_len -= hdr_len;
|
||||
if ((clnp->cnf_type & CNF_SEG_OK) &&
|
||||
(total_len >= 8) &&
|
||||
(frag_size > 8 || (frag_size == 8 && !(total_len & 7)))) {
|
||||
|
||||
struct mbuf *hdr = NULL; /* save copy of clnp hdr */
|
||||
struct mbuf *frag_hdr = NULL;
|
||||
struct mbuf *frag_data = NULL;
|
||||
struct clnp_segment seg_part; /* segmentation header */
|
||||
int frag_base;
|
||||
int error = 0;
|
||||
|
||||
|
||||
INCSTAT(cns_fragmented);
|
||||
(void) bcopy(segoff + mtod(m, caddr_t), (caddr_t)&seg_part,
|
||||
sizeof(seg_part));
|
||||
frag_base = ntohs(seg_part.cng_off);
|
||||
/*
|
||||
* Duplicate header, and remove from packet
|
||||
*/
|
||||
if ((hdr = m_copy(m, 0, hdr_len)) == NULL) {
|
||||
clnp_discard(m, GEN_CONGEST);
|
||||
return(ENOBUFS);
|
||||
}
|
||||
m_adj(m, hdr_len);
|
||||
|
||||
while (total_len > 0) {
|
||||
int remaining, last_frag;
|
||||
|
||||
IFDEBUG(D_FRAG)
|
||||
struct mbuf *mdump = frag_hdr;
|
||||
int tot_mlen = 0;
|
||||
printf("clnp_fragment: total_len %d:\n", total_len);
|
||||
while (mdump != NULL) {
|
||||
printf("\tmbuf x%x, m_len %d\n",
|
||||
mdump, mdump->m_len);
|
||||
tot_mlen += mdump->m_len;
|
||||
mdump = mdump->m_next;
|
||||
}
|
||||
printf("clnp_fragment: sum of mbuf chain %d:\n", tot_mlen);
|
||||
ENDDEBUG
|
||||
|
||||
frag_size = min(total_len, frag_size);
|
||||
if ((remaining = total_len - frag_size) == 0)
|
||||
last_frag = 1;
|
||||
else {
|
||||
/*
|
||||
* If this fragment will cause the last one to
|
||||
* be less than 8 bytes, shorten this fragment a bit.
|
||||
* The obscure test on frag_size above ensures that
|
||||
* frag_size will be positive.
|
||||
*/
|
||||
last_frag = 0;
|
||||
if (remaining < 8)
|
||||
frag_size -= 8;
|
||||
}
|
||||
|
||||
|
||||
IFDEBUG(D_FRAG)
|
||||
printf("clnp_fragment: seg off %d, size %d, remaining %d\n",
|
||||
ntohs(seg_part.cng_off), frag_size, total_len-frag_size);
|
||||
if (last_frag)
|
||||
printf("clnp_fragment: last fragment\n");
|
||||
ENDDEBUG
|
||||
|
||||
if (last_frag) {
|
||||
/*
|
||||
* this is the last fragment; we don't need to get any other
|
||||
* mbufs.
|
||||
*/
|
||||
frag_hdr = hdr;
|
||||
frag_data = m;
|
||||
} else {
|
||||
/* duplicate header and data mbufs */
|
||||
if ((frag_hdr = m_copy(hdr, 0, (int)M_COPYALL)) == NULL) {
|
||||
clnp_discard(hdr, GEN_CONGEST);
|
||||
m_freem(m);
|
||||
return(ENOBUFS);
|
||||
}
|
||||
if ((frag_data = m_copy(m, 0, frag_size)) == NULL) {
|
||||
clnp_discard(hdr, GEN_CONGEST);
|
||||
m_freem(m);
|
||||
m_freem(frag_hdr);
|
||||
return(ENOBUFS);
|
||||
}
|
||||
INCSTAT(cns_fragments);
|
||||
}
|
||||
clnp = mtod(frag_hdr, struct clnp_fixed *);
|
||||
|
||||
if (!last_frag)
|
||||
clnp->cnf_type |= CNF_MORE_SEGS;
|
||||
|
||||
/* link together */
|
||||
m_cat(frag_hdr, frag_data);
|
||||
|
||||
/* insert segmentation part; updated below */
|
||||
bcopy((caddr_t)&seg_part, mtod(frag_hdr, caddr_t) + segoff,
|
||||
sizeof(struct clnp_segment));
|
||||
|
||||
{
|
||||
int derived_len = hdr_len + frag_size;
|
||||
HTOC(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, derived_len);
|
||||
if ((frag_hdr->m_flags & M_PKTHDR) == 0)
|
||||
panic("clnp_frag:lost header");
|
||||
frag_hdr->m_pkthdr.len = derived_len;
|
||||
}
|
||||
/* compute clnp checksum (on header only) */
|
||||
if (flags & CLNP_NO_CKSUM) {
|
||||
HTOC(clnp->cnf_cksum_msb, clnp->cnf_cksum_lsb, 0);
|
||||
} else {
|
||||
iso_gen_csum(frag_hdr, CLNP_CKSUM_OFF, hdr_len);
|
||||
}
|
||||
|
||||
IFDEBUG(D_DUMPOUT)
|
||||
struct mbuf *mdump = frag_hdr;
|
||||
printf("clnp_fragment: sending dg:\n");
|
||||
while (mdump != NULL) {
|
||||
printf("\tmbuf x%x, m_len %d\n", mdump, mdump->m_len);
|
||||
mdump = mdump->m_next;
|
||||
}
|
||||
ENDDEBUG
|
||||
|
||||
#ifdef TROLL
|
||||
error = troll_output(ifp, frag_hdr, first_hop, rt);
|
||||
#else
|
||||
error = (*ifp->if_output)(ifp, frag_hdr, first_hop, rt);
|
||||
#endif /* TROLL */
|
||||
|
||||
/*
|
||||
* Tough situation: if the error occured on the last
|
||||
* fragment, we can not send an ER, as the if_output
|
||||
* routine consumed the packet. If the error occured
|
||||
* on any intermediate packets, we can send an ER
|
||||
* because we still have the original header in (m).
|
||||
*/
|
||||
if (error) {
|
||||
if (frag_hdr != hdr) {
|
||||
/*
|
||||
* The error was not on the last fragment. We must
|
||||
* free hdr and m before returning
|
||||
*/
|
||||
clnp_discard(hdr, GEN_NOREAS);
|
||||
m_freem(m);
|
||||
}
|
||||
return(error);
|
||||
}
|
||||
|
||||
/* bump segment offset, trim data mbuf, and decrement count left */
|
||||
#ifdef TROLL
|
||||
/*
|
||||
* Decrement frag_size by some fraction. This will cause the
|
||||
* next fragment to start 'early', thus duplicating the end
|
||||
* of the current fragment. troll.tr_dup_size controls
|
||||
* the fraction. If positive, it specifies the fraction. If
|
||||
* negative, a random fraction is used.
|
||||
*/
|
||||
if ((trollctl.tr_ops & TR_DUPEND) && (!last_frag)) {
|
||||
int num_bytes = frag_size;
|
||||
|
||||
if (trollctl.tr_dup_size > 0)
|
||||
num_bytes *= trollctl.tr_dup_size;
|
||||
else
|
||||
num_bytes *= troll_random();
|
||||
frag_size -= num_bytes;
|
||||
}
|
||||
#endif /* TROLL */
|
||||
total_len -= frag_size;
|
||||
if (!last_frag) {
|
||||
frag_base += frag_size;
|
||||
seg_part.cng_off = htons(frag_base);
|
||||
m_adj(m, frag_size);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
} else {
|
||||
cantfrag:
|
||||
INCSTAT(cns_cantfrag);
|
||||
clnp_discard(m, GEN_SEGNEEDED);
|
||||
return(EMSGSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_reass
|
||||
*
|
||||
* PURPOSE: Attempt to reassemble a clnp packet given the current
|
||||
* fragment. If reassembly succeeds (all the fragments
|
||||
* are present), then return a pointer to an mbuf chain
|
||||
* containing the reassembled packet. This packet will
|
||||
* appear in the mbufs as if it had just arrived in
|
||||
* one piece.
|
||||
*
|
||||
* If reassembly fails, then save this fragment and
|
||||
* return 0.
|
||||
*
|
||||
* RETURNS: Ptr to assembled packet, or 0
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
* clnp_slowtimo can not affect this code because clnpintr, and thus
|
||||
* this code, is called at a higher priority than clnp_slowtimo.
|
||||
*/
|
||||
struct mbuf *
|
||||
clnp_reass(m, src, dst, seg)
|
||||
struct mbuf *m; /* new fragment */
|
||||
struct iso_addr *src; /* src of new fragment */
|
||||
struct iso_addr *dst; /* dst of new fragment */
|
||||
struct clnp_segment *seg; /* segment part of fragment header */
|
||||
{
|
||||
register struct clnp_fragl *cfh;
|
||||
|
||||
/* look for other fragments of this datagram */
|
||||
for (cfh = clnp_frags; cfh != NULL; cfh = cfh->cfl_next) {
|
||||
if (seg->cng_id == cfh->cfl_id &&
|
||||
iso_addrmatch1(src, &cfh->cfl_src) &&
|
||||
iso_addrmatch1(dst, &cfh->cfl_dst)) {
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_reass: found packet\n");
|
||||
ENDDEBUG
|
||||
/*
|
||||
* There are other fragments here already. Lets see if
|
||||
* this fragment is of any help
|
||||
*/
|
||||
clnp_insert_frag(cfh, m, seg);
|
||||
if (m = clnp_comp_pdu(cfh)) {
|
||||
register struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
|
||||
HTOC(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb,
|
||||
seg->cng_tot_len);
|
||||
}
|
||||
return (m);
|
||||
}
|
||||
}
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_reass: new packet!\n");
|
||||
ENDDEBUG
|
||||
|
||||
/*
|
||||
* This is the first fragment. If src is not consuming too many
|
||||
* resources, then create a new fragment list and add
|
||||
* this fragment to the list.
|
||||
*/
|
||||
/* TODO: don't let one src hog all the reassembly buffers */
|
||||
if (!clnp_newpkt(m, src, dst, seg) /* || this src is a hog */) {
|
||||
INCSTAT(cns_fragdropped);
|
||||
clnp_discard(m, GEN_CONGEST);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_newpkt
|
||||
*
|
||||
* PURPOSE: Create the necessary structures to handle a new
|
||||
* fragmented clnp packet.
|
||||
*
|
||||
* RETURNS: non-zero if it succeeds, zero if fails.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: Failure is only due to insufficient resources.
|
||||
*/
|
||||
clnp_newpkt(m, src, dst, seg)
|
||||
struct mbuf *m; /* new fragment */
|
||||
struct iso_addr *src; /* src of new fragment */
|
||||
struct iso_addr *dst; /* dst of new fragment */
|
||||
struct clnp_segment *seg; /* segment part of fragment header */
|
||||
{
|
||||
register struct clnp_fragl *cfh;
|
||||
register struct clnp_fixed *clnp;
|
||||
struct mbuf *m0;
|
||||
|
||||
clnp = mtod(m, struct clnp_fixed *);
|
||||
|
||||
/*
|
||||
* Allocate new clnp fragl structure to act as header of all fragments
|
||||
* for this datagram.
|
||||
*/
|
||||
MGET(m0, M_DONTWAIT, MT_FTABLE);
|
||||
if (m0 == NULL) {
|
||||
return (0);
|
||||
}
|
||||
cfh = mtod(m0, struct clnp_fragl *);
|
||||
|
||||
/*
|
||||
* Duplicate the header of this fragment, and save in cfh.
|
||||
* Free m0 and return if m_copy does not succeed.
|
||||
*/
|
||||
if ((cfh->cfl_orighdr = m_copy(m, 0, (int)clnp->cnf_hdr_len)) == NULL) {
|
||||
m_freem(m0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Fill in rest of fragl structure */
|
||||
bcopy((caddr_t)src, (caddr_t)&cfh->cfl_src, sizeof(struct iso_addr));
|
||||
bcopy((caddr_t)dst, (caddr_t)&cfh->cfl_dst, sizeof(struct iso_addr));
|
||||
cfh->cfl_id = seg->cng_id;
|
||||
cfh->cfl_ttl = clnp->cnf_ttl;
|
||||
cfh->cfl_last = (seg->cng_tot_len - clnp->cnf_hdr_len) - 1;
|
||||
cfh->cfl_frags = NULL;
|
||||
cfh->cfl_next = NULL;
|
||||
|
||||
/* Insert into list of packets */
|
||||
cfh->cfl_next = clnp_frags;
|
||||
clnp_frags = cfh;
|
||||
|
||||
/* Insert this fragment into list headed by cfh */
|
||||
clnp_insert_frag(cfh, m, seg);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_insert_frag
|
||||
*
|
||||
* PURPOSE: Insert fragment into list headed by 'cf'.
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: This is the 'guts' of the reassembly algorithm.
|
||||
* Each fragment in this list contains a clnp_frag
|
||||
* structure followed by the data of the fragment.
|
||||
* The clnp_frag structure actually lies on top of
|
||||
* part of the old clnp header.
|
||||
*/
|
||||
clnp_insert_frag(cfh, m, seg)
|
||||
struct clnp_fragl *cfh; /* header of list of packet fragments */
|
||||
struct mbuf *m; /* new fragment */
|
||||
struct clnp_segment *seg; /* segment part of fragment header */
|
||||
{
|
||||
register struct clnp_fixed *clnp; /* clnp hdr of fragment */
|
||||
register struct clnp_frag *cf; /* generic fragment ptr */
|
||||
register struct clnp_frag *cf_sub = NULL; /* frag subsequent to new one */
|
||||
register struct clnp_frag *cf_prev = NULL; /* frag previous to new one */
|
||||
u_short first; /* offset of first byte of initial pdu*/
|
||||
u_short last; /* offset of last byte of initial pdu */
|
||||
u_short fraglen;/* length of fragment */
|
||||
|
||||
clnp = mtod(m, struct clnp_fixed *);
|
||||
first = seg->cng_off;
|
||||
CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, fraglen);
|
||||
fraglen -= clnp->cnf_hdr_len;
|
||||
last = (first + fraglen) - 1;
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_insert_frag: New fragment: [%d ... %d], len %d\n",
|
||||
first, last, fraglen);
|
||||
printf("clnp_insert_frag: current fragments:\n");
|
||||
for (cf = cfh->cfl_frags; cf != NULL; cf = cf->cfr_next) {
|
||||
printf("\tcf x%x: [%d ... %d]\n", cf, cf->cfr_first, cf->cfr_last);
|
||||
}
|
||||
ENDDEBUG
|
||||
|
||||
if (cfh->cfl_frags != NULL) {
|
||||
/*
|
||||
* Find fragment which begins after the new one
|
||||
*/
|
||||
for (cf = cfh->cfl_frags; cf != NULL; cf_prev = cf, cf = cf->cfr_next) {
|
||||
if (cf->cfr_first > first) {
|
||||
cf_sub = cf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_insert_frag: Previous frag is ");
|
||||
if (cf_prev == NULL)
|
||||
printf("NULL\n");
|
||||
else
|
||||
printf("[%d ... %d]\n", cf_prev->cfr_first, cf_prev->cfr_last);
|
||||
printf("clnp_insert_frag: Subsequent frag is ");
|
||||
if (cf_sub == NULL)
|
||||
printf("NULL\n");
|
||||
else
|
||||
printf("[%d ... %d]\n", cf_sub->cfr_first, cf_sub->cfr_last);
|
||||
ENDDEBUG
|
||||
|
||||
/*
|
||||
* If there is a fragment before the new one, check if it
|
||||
* overlaps the new one. If so, then trim the end of the
|
||||
* previous one.
|
||||
*/
|
||||
if (cf_prev != NULL) {
|
||||
if (cf_prev->cfr_last > first) {
|
||||
u_short overlap = cf_prev->cfr_last - first;
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_insert_frag: previous overlaps by %d\n",
|
||||
overlap);
|
||||
ENDDEBUG
|
||||
|
||||
if (overlap > fraglen) {
|
||||
/*
|
||||
* The new fragment is entirely contained in the
|
||||
* preceeding one. We can punt on the new frag
|
||||
* completely.
|
||||
*/
|
||||
m_freem(m);
|
||||
return;
|
||||
} else {
|
||||
/* Trim data off of end of previous fragment */
|
||||
/* inc overlap to prevent duplication of last byte */
|
||||
overlap++;
|
||||
m_adj(cf_prev->cfr_data, -(int)overlap);
|
||||
cf_prev->cfr_last -= overlap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For all fragments past the new one, check if any data on
|
||||
* the new one overlaps data on existing fragments. If so,
|
||||
* then trim the extra data off the end of the new one.
|
||||
*/
|
||||
for (cf = cf_sub; cf != NULL; cf = cf->cfr_next) {
|
||||
if (cf->cfr_first < last) {
|
||||
u_short overlap = last - cf->cfr_first;
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_insert_frag: subsequent overlaps by %d\n",
|
||||
overlap);
|
||||
ENDDEBUG
|
||||
|
||||
if (overlap > fraglen) {
|
||||
/*
|
||||
* The new fragment is entirely contained in the
|
||||
* succeeding one. This should not happen, because
|
||||
* early on in this code we scanned for the fragment
|
||||
* which started after the new one!
|
||||
*/
|
||||
m_freem(m);
|
||||
printf("clnp_insert_frag: internal error!\n");
|
||||
return;
|
||||
} else {
|
||||
/* Trim data off of end of new fragment */
|
||||
/* inc overlap to prevent duplication of last byte */
|
||||
overlap++;
|
||||
m_adj(m, -(int)overlap);
|
||||
last -= overlap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the new fragment beween cf_prev and cf_sub
|
||||
*
|
||||
* Note: the clnp hdr is still in the mbuf.
|
||||
* If the data of the mbuf is not word aligned, shave off enough
|
||||
* so that it is. Then, cast the clnp_frag structure on top
|
||||
* of the clnp header.
|
||||
* The clnp_hdr will not be used again (as we already have
|
||||
* saved a copy of it).
|
||||
*
|
||||
* Save in cfr_bytes the number of bytes to shave off to get to
|
||||
* the data of the packet. This is used when we coalesce fragments;
|
||||
* the clnp_frag structure must be removed before joining mbufs.
|
||||
*/
|
||||
{
|
||||
int pad;
|
||||
u_int bytes;
|
||||
|
||||
/* determine if header is not word aligned */
|
||||
pad = (int)clnp % 4;
|
||||
if (pad < 0)
|
||||
pad = -pad;
|
||||
|
||||
/* bytes is number of bytes left in front of data */
|
||||
bytes = clnp->cnf_hdr_len - pad;
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_insert_frag: clnp x%x requires %d alignment\n",
|
||||
clnp, pad);
|
||||
ENDDEBUG
|
||||
|
||||
/* make it word aligned if necessary */
|
||||
if (pad)
|
||||
m_adj(m, pad);
|
||||
|
||||
cf = mtod(m, struct clnp_frag *);
|
||||
cf->cfr_bytes = bytes;
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_insert_frag: cf now x%x, cfr_bytes %d\n", cf,
|
||||
cf->cfr_bytes);
|
||||
ENDDEBUG
|
||||
}
|
||||
cf->cfr_first = first;
|
||||
cf->cfr_last = last;
|
||||
|
||||
|
||||
/*
|
||||
* The data is the mbuf itself, although we must remember that the
|
||||
* first few bytes are actually a clnp_frag structure
|
||||
*/
|
||||
cf->cfr_data = m;
|
||||
|
||||
/* link into place */
|
||||
cf->cfr_next = cf_sub;
|
||||
if (cf_prev == NULL)
|
||||
cfh->cfl_frags = cf;
|
||||
else
|
||||
cf_prev->cfr_next = cf;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_comp_pdu
|
||||
*
|
||||
* PURPOSE: Scan the list of fragments headed by cfh. Merge
|
||||
* any contigious fragments into one. If, after
|
||||
* traversing all the fragments, it is determined that
|
||||
* the packet is complete, then return a pointer to
|
||||
* the packet (with header prepended). Otherwise,
|
||||
* return NULL.
|
||||
*
|
||||
* RETURNS: NULL, or a pointer to the assembled pdu in an mbuf chain.
|
||||
*
|
||||
* SIDE EFFECTS: Will colapse contigious fragments into one.
|
||||
*
|
||||
* NOTES: This code assumes that there are no overlaps of
|
||||
* fragment pdus.
|
||||
*/
|
||||
struct mbuf *
|
||||
clnp_comp_pdu(cfh)
|
||||
struct clnp_fragl *cfh; /* fragment header */
|
||||
{
|
||||
register struct clnp_frag *cf = cfh->cfl_frags;
|
||||
|
||||
while (cf->cfr_next != NULL) {
|
||||
register struct clnp_frag *cf_next = cf->cfr_next;
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_comp_pdu: comparing: [%d ... %d] to [%d ... %d]\n",
|
||||
cf->cfr_first, cf->cfr_last, cf_next->cfr_first,
|
||||
cf_next->cfr_last);
|
||||
ENDDEBUG
|
||||
|
||||
if (cf->cfr_last == (cf_next->cfr_first - 1)) {
|
||||
/*
|
||||
* Merge fragment cf and cf_next
|
||||
*
|
||||
* - update cf header
|
||||
* - trim clnp_frag structure off of cf_next
|
||||
* - append cf_next to cf
|
||||
*/
|
||||
struct clnp_frag cf_next_hdr;
|
||||
struct clnp_frag *next_frag;
|
||||
|
||||
cf_next_hdr = *cf_next;
|
||||
next_frag = cf_next->cfr_next;
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
struct mbuf *mdump;
|
||||
int l;
|
||||
printf("clnp_comp_pdu: merging fragments\n");
|
||||
printf("clnp_comp_pdu: 1st: [%d ... %d] (bytes %d)\n",
|
||||
cf->cfr_first, cf->cfr_last, cf->cfr_bytes);
|
||||
mdump = cf->cfr_data;
|
||||
l = 0;
|
||||
while (mdump != NULL) {
|
||||
printf("\tmbuf x%x, m_len %d\n", mdump, mdump->m_len);
|
||||
l += mdump->m_len;
|
||||
mdump = mdump->m_next;
|
||||
}
|
||||
printf("\ttotal len: %d\n", l);
|
||||
printf("clnp_comp_pdu: 2nd: [%d ... %d] (bytes %d)\n",
|
||||
cf_next->cfr_first, cf_next->cfr_last, cf_next->cfr_bytes);
|
||||
mdump = cf_next->cfr_data;
|
||||
l = 0;
|
||||
while (mdump != NULL) {
|
||||
printf("\tmbuf x%x, m_len %d\n", mdump, mdump->m_len);
|
||||
l += mdump->m_len;
|
||||
mdump = mdump->m_next;
|
||||
}
|
||||
printf("\ttotal len: %d\n", l);
|
||||
ENDDEBUG
|
||||
|
||||
cf->cfr_last = cf_next->cfr_last;
|
||||
/*
|
||||
* After this m_adj, the cf_next ptr is useless because we
|
||||
* have adjusted the clnp_frag structure away...
|
||||
*/
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_comp_pdu: shaving off %d bytes\n",
|
||||
cf_next_hdr.cfr_bytes);
|
||||
ENDDEBUG
|
||||
m_adj(cf_next_hdr.cfr_data, (int)cf_next_hdr.cfr_bytes);
|
||||
m_cat(cf->cfr_data, cf_next_hdr.cfr_data);
|
||||
cf->cfr_next = next_frag;
|
||||
} else {
|
||||
cf = cf->cfr_next;
|
||||
}
|
||||
}
|
||||
|
||||
cf = cfh->cfl_frags;
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
struct mbuf *mdump = cf->cfr_data;
|
||||
printf("clnp_comp_pdu: first frag now: [%d ... %d]\n", cf->cfr_first,
|
||||
cf->cfr_last);
|
||||
printf("clnp_comp_pdu: data for frag:\n");
|
||||
while (mdump != NULL) {
|
||||
printf("mbuf x%x, m_len %d\n", mdump, mdump->m_len);
|
||||
/* dump_buf(mtod(mdump, caddr_t), mdump->m_len);*/
|
||||
mdump = mdump->m_next;
|
||||
}
|
||||
ENDDEBUG
|
||||
|
||||
/* Check if datagram is complete */
|
||||
if ((cf->cfr_first == 0) && (cf->cfr_last == cfh->cfl_last)) {
|
||||
/*
|
||||
* We have a complete pdu!
|
||||
* - Remove the frag header from (only) remaining fragment
|
||||
* (which is not really a fragment anymore, as the datagram is
|
||||
* complete).
|
||||
* - Prepend a clnp header
|
||||
*/
|
||||
struct mbuf *data = cf->cfr_data;
|
||||
struct mbuf *hdr = cfh->cfl_orighdr;
|
||||
struct clnp_fragl *scan;
|
||||
|
||||
IFDEBUG(D_REASS)
|
||||
printf("clnp_comp_pdu: complete pdu!\n");
|
||||
ENDDEBUG
|
||||
|
||||
m_adj(data, (int)cf->cfr_bytes);
|
||||
m_cat(hdr, data);
|
||||
|
||||
IFDEBUG(D_DUMPIN)
|
||||
struct mbuf *mdump = hdr;
|
||||
printf("clnp_comp_pdu: pdu is:\n");
|
||||
while (mdump != NULL) {
|
||||
printf("mbuf x%x, m_len %d\n", mdump, mdump->m_len);
|
||||
/* dump_buf(mtod(mdump, caddr_t), mdump->m_len);*/
|
||||
mdump = mdump->m_next;
|
||||
}
|
||||
ENDDEBUG
|
||||
|
||||
/*
|
||||
* Remove cfh from the list of fragmented pdus
|
||||
*/
|
||||
if (clnp_frags == cfh) {
|
||||
clnp_frags = cfh->cfl_next;
|
||||
} else {
|
||||
for (scan = clnp_frags; scan != NULL; scan = scan->cfl_next) {
|
||||
if (scan->cfl_next == cfh) {
|
||||
scan->cfl_next = cfh->cfl_next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free cfh */
|
||||
m_freem(dtom(cfh));
|
||||
|
||||
return(hdr);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
#ifdef TROLL
|
||||
static int troll_cnt;
|
||||
#include <sys/time.h>
|
||||
/*
|
||||
* FUNCTION: troll_random
|
||||
*
|
||||
* PURPOSE: generate a pseudo-random number between 0 and 1
|
||||
*
|
||||
* RETURNS: the random number
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: This is based on the clock.
|
||||
*/
|
||||
float troll_random()
|
||||
{
|
||||
extern struct timeval time;
|
||||
long t = time.tv_usec % 100;
|
||||
|
||||
return((float)t / (float) 100);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: troll_output
|
||||
*
|
||||
* PURPOSE: Do something sneaky with the datagram passed. Possible
|
||||
* operations are:
|
||||
* Duplicate the packet
|
||||
* Drop the packet
|
||||
* Trim some number of bytes from the packet
|
||||
* Munge some byte in the packet
|
||||
*
|
||||
* RETURNS: 0, or unix error code
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: The operation of this procedure is regulated by the
|
||||
* troll control structure (Troll).
|
||||
*/
|
||||
troll_output(ifp, m, dst, rt)
|
||||
struct ifnet *ifp;
|
||||
struct mbuf *m;
|
||||
struct sockaddr *dst;
|
||||
struct rtentry *rt;
|
||||
{
|
||||
int err = 0;
|
||||
troll_cnt++;
|
||||
|
||||
if (trollctl.tr_ops & TR_DUPPKT) {
|
||||
/*
|
||||
* Duplicate every Nth packet
|
||||
* TODO: random?
|
||||
*/
|
||||
float f_freq = troll_cnt * trollctl.tr_dup_freq;
|
||||
int i_freq = troll_cnt * trollctl.tr_dup_freq;
|
||||
if (i_freq == f_freq) {
|
||||
struct mbuf *dup = m_copy(m, 0, (int)M_COPYALL);
|
||||
if (dup != NULL)
|
||||
err = (*ifp->if_output)(ifp, dup, dst, rt);
|
||||
}
|
||||
if (!err)
|
||||
err = (*ifp->if_output)(ifp, m, dst, rt);
|
||||
return(err);
|
||||
} else if (trollctl.tr_ops & TR_DROPPKT) {
|
||||
} else if (trollctl.tr_ops & TR_CHANGE) {
|
||||
struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
|
||||
clnp->cnf_cksum_msb = 0;
|
||||
err = (*ifp->if_output)(ifp, m, dst, rt);
|
||||
return(err);
|
||||
} else {
|
||||
err = (*ifp->if_output)(ifp, m, dst, rt);
|
||||
return(err);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* TROLL */
|
||||
@@ -1,556 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp_input.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnp_input.c,v 1.5 1995/05/11 00:13:20 wollman Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp_input.c,v 1.5 1995/05/11 00:13:20 wollman Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp_input.c,v $ */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/iso_snpac.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/clnl.h>
|
||||
#include <netiso/esis.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netiso/eonvar.h>
|
||||
#include <netiso/clnp_stat.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
|
||||
#ifdef ISO
|
||||
u_char clnp_protox[ISOPROTO_MAX];
|
||||
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();
|
||||
|
||||
#ifdef ISO_X25ESIS
|
||||
int x25esis_input();
|
||||
#endif /* ISO_X25ESIS */
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_init
|
||||
*
|
||||
* PURPOSE: clnp initialization. Fill in clnp switch tables.
|
||||
*
|
||||
* RETURNS: none
|
||||
*
|
||||
* SIDE EFFECTS: fills in clnp_protox table with correct offsets into
|
||||
* the isosw table.
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
clnp_init()
|
||||
{
|
||||
register struct protosw *pr;
|
||||
|
||||
/*
|
||||
* CLNP protox initialization
|
||||
*/
|
||||
if ((pr = pffindproto(PF_ISO, ISOPROTO_RAW, SOCK_RAW)) == 0)
|
||||
printf("clnl_init: no raw CLNP\n");
|
||||
else
|
||||
clnp_protox[ISOPROTO_RAW] = pr - isosw;
|
||||
|
||||
if ((pr = pffindproto(PF_ISO, ISOPROTO_TP, SOCK_SEQPACKET)) == 0)
|
||||
printf("clnl_init: no tp/clnp\n");
|
||||
else
|
||||
clnp_protox[ISOPROTO_TP] = pr - isosw;
|
||||
|
||||
/*
|
||||
* CLNL protox initialization
|
||||
*/
|
||||
clnl_protox[ISO8473_CLNP].clnl_input = clnp_input;
|
||||
|
||||
clnlintrq.ifq_maxlen = clnpqmaxlen;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnlintr
|
||||
*
|
||||
* PURPOSE: Process a packet on the clnl input queue
|
||||
*
|
||||
* RETURNS: nothing.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
void
|
||||
clnlintr(void)
|
||||
{
|
||||
register struct mbuf *m; /* ptr to first mbuf of pkt */
|
||||
register struct clnl_fixed *clnl; /* ptr to fixed part of clnl hdr */
|
||||
int s; /* save and restore priority */
|
||||
struct clnl_protosw *clnlsw;/* ptr to protocol switch */
|
||||
struct snpa_hdr sh; /* subnetwork hdr */
|
||||
|
||||
/*
|
||||
* Get next datagram off clnl input queue
|
||||
*/
|
||||
next:
|
||||
s = splimp();
|
||||
/* IF_DEQUEUESNPAHDR(&clnlintrq, m, sh);*/
|
||||
IF_DEQUEUE(&clnlintrq, m);
|
||||
splx(s);
|
||||
|
||||
|
||||
if (m == 0) /* nothing to do */
|
||||
return;
|
||||
if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.rcvif == 0) {
|
||||
m_freem(m);
|
||||
goto next;
|
||||
} else {
|
||||
register struct ifaddr *ifa;
|
||||
for (ifa = m->m_pkthdr.rcvif->if_addrlist; ifa; ifa = ifa->ifa_next)
|
||||
if (ifa->ifa_addr->sa_family == AF_ISO)
|
||||
break;
|
||||
if (ifa == 0) {
|
||||
m_freem(m);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
bzero((caddr_t)&sh, sizeof(sh));
|
||||
sh.snh_flags = m->m_flags & (M_MCAST|M_BCAST);
|
||||
switch((sh.snh_ifp = m->m_pkthdr.rcvif)->if_type) {
|
||||
extern int ether_output();
|
||||
case IFT_EON:
|
||||
bcopy(mtod(m, caddr_t), (caddr_t)sh.snh_dhost, sizeof(u_long));
|
||||
bcopy(sizeof(u_long) + mtod(m, caddr_t),
|
||||
(caddr_t)sh.snh_shost, sizeof(u_long));
|
||||
sh.snh_dhost[4] = mtod(m, u_char *)[sizeof(struct ip) +
|
||||
_offsetof(struct eon_hdr, eonh_class)];
|
||||
m->m_data += EONIPLEN;
|
||||
m->m_len -= EONIPLEN;
|
||||
m->m_pkthdr.len -= EONIPLEN;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (sh.snh_ifp->if_output == ether_output) {
|
||||
bcopy((caddr_t)(mtod(m, struct ether_header *)->ether_dhost),
|
||||
(caddr_t)sh.snh_dhost, 2*sizeof(sh.snh_dhost));
|
||||
m->m_data += sizeof (struct ether_header);
|
||||
m->m_len -= sizeof (struct ether_header);
|
||||
m->m_pkthdr.len -= sizeof (struct ether_header);
|
||||
}
|
||||
}
|
||||
IFDEBUG(D_INPUT)
|
||||
int i;
|
||||
printf("clnlintr: src:");
|
||||
for (i=0; i<6; i++)
|
||||
printf("%x%c", sh.snh_shost[i] & 0xff, (i<5) ? ':' : ' ');
|
||||
printf(" dst:");
|
||||
for (i=0; i<6; i++)
|
||||
printf("%x%c", sh.snh_dhost[i] & 0xff, (i<5) ? ':' : ' ');
|
||||
printf("\n");
|
||||
ENDDEBUG
|
||||
|
||||
/*
|
||||
* Get the fixed part of the clnl header into the first mbuf.
|
||||
* Drop the packet if this fails.
|
||||
* Do not call m_pullup if we have a cluster mbuf or the
|
||||
* data is not there.
|
||||
*/
|
||||
if ((IS_CLUSTER(m) || (m->m_len < sizeof(struct clnl_fixed))) &&
|
||||
((m = m_pullup(m, sizeof(struct clnl_fixed))) == 0)) {
|
||||
INCSTAT(cns_toosmall); /* TODO: use clnl stats */
|
||||
goto next; /* m_pullup discards mbuf */
|
||||
}
|
||||
|
||||
clnl = mtod(m, struct clnl_fixed *);
|
||||
|
||||
/*
|
||||
* Drop packet if the length of the header is not reasonable.
|
||||
*/
|
||||
if ((clnl->cnf_hdr_len < CLNP_HDR_MIN) ||
|
||||
(clnl->cnf_hdr_len > CLNP_HDR_MAX)) {
|
||||
INCSTAT(cns_badhlen); /* TODO: use clnl stats */
|
||||
m_freem(m);
|
||||
goto next;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the header is not contained in this mbuf, make it so.
|
||||
* Drop packet if this fails.
|
||||
* Note: m_pullup will allocate a cluster mbuf if necessary
|
||||
*/
|
||||
if (clnl->cnf_hdr_len > m->m_len) {
|
||||
if ((m = m_pullup(m, (int)clnl->cnf_hdr_len)) == 0) {
|
||||
INCSTAT(cns_badhlen); /* TODO: use clnl stats */
|
||||
goto next; /* m_pullup discards mbuf */
|
||||
}
|
||||
clnl = mtod(m, struct clnl_fixed *);
|
||||
}
|
||||
|
||||
clnlsw = &clnl_protox[clnl->cnf_proto_id];
|
||||
|
||||
|
||||
if (clnlsw->clnl_input)
|
||||
(*clnlsw->clnl_input) (m, &sh);
|
||||
else
|
||||
m_freem(m);
|
||||
|
||||
goto next;
|
||||
}
|
||||
|
||||
NETISR_SET(NETISR_ISO, clnlintr);
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_input
|
||||
*
|
||||
* PURPOSE: process an incoming clnp packet
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*
|
||||
* SIDE EFFECTS: increments fields of clnp_stat structure.
|
||||
*
|
||||
* NOTES:
|
||||
* TODO: I would like to make seg_part a pointer into the mbuf, but
|
||||
* will it be correctly aligned?
|
||||
*/
|
||||
clnp_input(m, shp)
|
||||
struct mbuf *m; /* ptr to first mbuf of pkt */
|
||||
struct snpa_hdr *shp; /* subnetwork header */
|
||||
{
|
||||
register struct clnp_fixed *clnp; /* ptr to fixed part of header */
|
||||
struct sockaddr_iso source; /* source address of pkt */
|
||||
struct sockaddr_iso target; /* destination address of pkt */
|
||||
#define src source.siso_addr
|
||||
#define dst target.siso_addr
|
||||
caddr_t hoff; /* current offset in packet */
|
||||
caddr_t hend; /* address of end of header info */
|
||||
struct clnp_segment seg_part; /* segment part of hdr */
|
||||
int seg_off=0; /* offset of segment part of hdr */
|
||||
int seg_len;/* length of packet data&hdr in bytes */
|
||||
struct clnp_optidx oidx, *oidxp = NULL; /* option index */
|
||||
extern int iso_systype; /* used by ESIS config resp */
|
||||
extern struct sockaddr_iso blank_siso; /* used for initializing */
|
||||
int need_afrin = 0;
|
||||
/* true if congestion experienced */
|
||||
/* which means you need afrin nose */
|
||||
/* spray. How clever! */
|
||||
|
||||
IFDEBUG(D_INPUT)
|
||||
printf(
|
||||
"clnp_input: proccessing dg; First mbuf m_len %d, m_type x%x, %s\n",
|
||||
m->m_len, m->m_type, IS_CLUSTER(m) ? "cluster" : "normal");
|
||||
ENDDEBUG
|
||||
need_afrin = 0;
|
||||
|
||||
/*
|
||||
* If no iso addresses have been set, there is nothing
|
||||
* to do with the packet.
|
||||
*/
|
||||
if (iso_ifaddr == NULL) {
|
||||
clnp_discard(m, ADDR_DESTUNREACH);
|
||||
return;
|
||||
}
|
||||
|
||||
INCSTAT(cns_total);
|
||||
clnp = mtod(m, struct clnp_fixed *);
|
||||
|
||||
IFDEBUG(D_DUMPIN)
|
||||
struct mbuf *mhead;
|
||||
int total_len = 0;
|
||||
printf("clnp_input: clnp header:\n");
|
||||
dump_buf(mtod(m, caddr_t), clnp->cnf_hdr_len);
|
||||
printf("clnp_input: mbuf chain:\n");
|
||||
for (mhead = m; mhead != NULL; mhead=mhead->m_next) {
|
||||
printf("m x%x, len %d\n", mhead, mhead->m_len);
|
||||
total_len += mhead->m_len;
|
||||
}
|
||||
printf("clnp_input: total length of mbuf chain %d:\n", total_len);
|
||||
ENDDEBUG
|
||||
|
||||
/*
|
||||
* Compute checksum (if necessary) and drop packet if
|
||||
* checksum does not match
|
||||
*/
|
||||
if (CKSUM_REQUIRED(clnp) && iso_check_csum(m, (int)clnp->cnf_hdr_len)) {
|
||||
INCSTAT(cns_badcsum);
|
||||
clnp_discard(m, GEN_BADCSUM);
|
||||
return;
|
||||
}
|
||||
|
||||
if (clnp->cnf_vers != ISO8473_V1) {
|
||||
INCSTAT(cns_badvers);
|
||||
clnp_discard(m, DISC_UNSUPPVERS);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* check mbuf data length: clnp_data_ck will free mbuf upon error */
|
||||
CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, seg_len);
|
||||
if ((m = clnp_data_ck(m, seg_len)) == 0)
|
||||
return;
|
||||
|
||||
clnp = mtod(m, struct clnp_fixed *);
|
||||
hend = (caddr_t)clnp + clnp->cnf_hdr_len;
|
||||
|
||||
/*
|
||||
* extract the source and destination address
|
||||
* drop packet on failure
|
||||
*/
|
||||
source = target = blank_siso;
|
||||
|
||||
hoff = (caddr_t)clnp + sizeof(struct clnp_fixed);
|
||||
CLNP_EXTRACT_ADDR(dst, hoff, hend);
|
||||
if (hoff == (caddr_t)0) {
|
||||
INCSTAT(cns_badaddr);
|
||||
clnp_discard(m, GEN_INCOMPLETE);
|
||||
return;
|
||||
}
|
||||
CLNP_EXTRACT_ADDR(src, hoff, hend);
|
||||
if (hoff == (caddr_t)0) {
|
||||
INCSTAT(cns_badaddr);
|
||||
clnp_discard(m, GEN_INCOMPLETE);
|
||||
return;
|
||||
}
|
||||
|
||||
IFDEBUG(D_INPUT)
|
||||
printf("clnp_input: from %s", clnp_iso_addrp(&src));
|
||||
printf(" to %s\n", clnp_iso_addrp(&dst));
|
||||
ENDDEBUG
|
||||
|
||||
/*
|
||||
* extract the segmentation information, if it is present.
|
||||
* drop packet on failure
|
||||
*/
|
||||
if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
|
||||
(clnp->cnf_type & CNF_SEG_OK)) {
|
||||
if (hoff + sizeof(struct clnp_segment) > hend) {
|
||||
INCSTAT(cns_noseg);
|
||||
clnp_discard(m, GEN_INCOMPLETE);
|
||||
return;
|
||||
} else {
|
||||
(void) bcopy(hoff, (caddr_t)&seg_part, sizeof(struct clnp_segment));
|
||||
/* make sure segmentation fields are in host order */
|
||||
seg_part.cng_id = ntohs(seg_part.cng_id);
|
||||
seg_part.cng_off = ntohs(seg_part.cng_off);
|
||||
seg_part.cng_tot_len = ntohs(seg_part.cng_tot_len);
|
||||
seg_off = hoff - (caddr_t)clnp;
|
||||
hoff += sizeof(struct clnp_segment);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* process options if present. If clnp_opt_sanity returns
|
||||
* false (indicating an error was found in the options) or
|
||||
* an unsupported option was found
|
||||
* then drop packet and emit an ER.
|
||||
*/
|
||||
if (hoff < hend) {
|
||||
int errcode;
|
||||
|
||||
oidxp = &oidx;
|
||||
errcode = clnp_opt_sanity(m, hoff, hend-hoff, oidxp);
|
||||
|
||||
/* we do not support security */
|
||||
if ((errcode == 0) && (oidxp->cni_securep))
|
||||
errcode = DISC_UNSUPPSECURE;
|
||||
|
||||
/* the er option is valid with ER pdus only */
|
||||
if ((errcode == 0) && (oidxp->cni_er_reason != ER_INVALREAS) &&
|
||||
((clnp->cnf_type & CNF_TYPE) != CLNP_ER))
|
||||
errcode = DISC_UNSUPPOPT;
|
||||
|
||||
#ifdef DECBIT
|
||||
/* check if the congestion experienced bit is set */
|
||||
if (oidxp->cni_qos_formatp) {
|
||||
caddr_t qosp = CLNP_OFFTOOPT(m, oidxp->cni_qos_formatp);
|
||||
u_char qos = *qosp;
|
||||
|
||||
need_afrin = ((qos & (CLNPOVAL_GLOBAL|CLNPOVAL_CONGESTED)) ==
|
||||
(CLNPOVAL_GLOBAL|CLNPOVAL_CONGESTED));
|
||||
if (need_afrin)
|
||||
INCSTAT(cns_congest_rcvd);
|
||||
}
|
||||
#endif /* DECBIT */
|
||||
|
||||
if (errcode != 0) {
|
||||
clnp_discard(m, (char)errcode);
|
||||
IFDEBUG(D_INPUT)
|
||||
printf("clnp_input: dropped (err x%x) due to bad options\n",
|
||||
errcode);
|
||||
ENDDEBUG
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check if this packet is for us. if not, then forward
|
||||
*/
|
||||
if (clnp_ours(&dst) == 0) {
|
||||
IFDEBUG(D_INPUT)
|
||||
printf("clnp_input: forwarding packet not for us\n");
|
||||
ENDDEBUG
|
||||
clnp_forward(m, seg_len, &dst, oidxp, seg_off, shp);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* ESIS Configuration Response Function
|
||||
*
|
||||
* If the packet received was sent to the multicast address
|
||||
* all end systems, then send an esh to the source
|
||||
*/
|
||||
if ((shp->snh_flags & M_MCAST) && (iso_systype == SNPA_ES)) {
|
||||
extern short esis_holding_time;
|
||||
|
||||
esis_shoutput(shp->snh_ifp, ESIS_ESH, esis_holding_time,
|
||||
shp->snh_shost, 6, &dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a fragment, then try to reassemble it. If clnp_reass
|
||||
* returns non NULL, the packet has been reassembled, and should
|
||||
* be give to TP. Otherwise the fragment has been delt with
|
||||
* by the reassembly code (either stored or deleted). In either case
|
||||
* we should have nothing more to do with it.
|
||||
*/
|
||||
if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
|
||||
(clnp->cnf_type & CNF_SEG_OK) &&
|
||||
(seg_len != seg_part.cng_tot_len)) {
|
||||
struct mbuf *m0;
|
||||
|
||||
if ((m0 = clnp_reass(m, &src, &dst, &seg_part)) != NULL) {
|
||||
m = m0;
|
||||
clnp = mtod(m, struct clnp_fixed *);
|
||||
INCSTAT(cns_reassembled);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* give the packet to the higher layer
|
||||
*
|
||||
* Note: the total length of packet
|
||||
* is the total length field of the segmentation part,
|
||||
* or, if absent, the segment length field of the
|
||||
* header.
|
||||
*/
|
||||
INCSTAT(cns_delivered);
|
||||
switch (clnp->cnf_type & CNF_TYPE) {
|
||||
case CLNP_ER:
|
||||
/*
|
||||
* This ER must have the er option.
|
||||
* If the option is not present, discard datagram.
|
||||
*/
|
||||
if (oidxp == NULL || oidxp->cni_er_reason == ER_INVALREAS) {
|
||||
clnp_discard(m, GEN_HDRSYNTAX);
|
||||
} else {
|
||||
clnp_er_input(m, &src, oidxp->cni_er_reason);
|
||||
}
|
||||
break;
|
||||
|
||||
case CLNP_DT:
|
||||
(*isosw[clnp_protox[ISOPROTO_TP]].pr_input)(m, &source, &target,
|
||||
clnp->cnf_hdr_len, need_afrin);
|
||||
break;
|
||||
|
||||
case CLNP_RAW:
|
||||
case CLNP_ECR:
|
||||
IFDEBUG(D_INPUT)
|
||||
printf("clnp_input: raw input of %d bytes\n",
|
||||
clnp->cnf_type & CNF_SEG_OK ? seg_part.cng_tot_len : seg_len);
|
||||
ENDDEBUG
|
||||
(*isosw[clnp_protox[ISOPROTO_RAW]].pr_input)(m, &source, &target,
|
||||
clnp->cnf_hdr_len);
|
||||
break;
|
||||
|
||||
case CLNP_EC:
|
||||
IFDEBUG(D_INPUT)
|
||||
printf("clnp_input: echoing packet\n");
|
||||
ENDDEBUG
|
||||
(void)clnp_echoreply(m,
|
||||
(clnp->cnf_type & CNF_SEG_OK ? (int)seg_part.cng_tot_len : seg_len),
|
||||
&source, &target, oidxp);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("clnp_input: unknown clnp pkt type %d\n",
|
||||
clnp->cnf_type & CNF_TYPE);
|
||||
clnp_stat.cns_delivered--;
|
||||
clnp_stat.cns_noproto++;
|
||||
clnp_discard(m, GEN_HDRSYNTAX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* ISO */
|
||||
@@ -1,533 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp_options.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnp_options.c,v 1.2 1994/08/02 07:49:40 davidg Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp_options.c,v 1.2 1994/08/02 07:49:40 davidg Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp_options.c,v $ */
|
||||
|
||||
#ifdef ISO
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/clnp_stat.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_update_srcrt
|
||||
*
|
||||
* PURPOSE: Process src rt option accompanying a clnp datagram.
|
||||
* - bump src route ptr if src routing and
|
||||
* we appear current in src route list.
|
||||
*
|
||||
* RETURNS: none
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: If source routing has been terminated, do nothing.
|
||||
*/
|
||||
clnp_update_srcrt(options, oidx)
|
||||
struct mbuf *options; /* ptr to options mbuf */
|
||||
struct clnp_optidx *oidx; /* ptr to option index */
|
||||
{
|
||||
u_char len; /* length of current address */
|
||||
struct iso_addr isoa; /* copy current address into here */
|
||||
|
||||
if (CLNPSRCRT_TERM(oidx, options)) {
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_update_srcrt: src rt terminated\n");
|
||||
ENDDEBUG
|
||||
return;
|
||||
}
|
||||
|
||||
len = CLNPSRCRT_CLEN(oidx, options);
|
||||
bcopy(CLNPSRCRT_CADDR(oidx, options), (caddr_t)&isoa, len);
|
||||
isoa.isoa_len = len;
|
||||
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_update_srcrt: current src rt: %s\n",
|
||||
clnp_iso_addrp(&isoa));
|
||||
ENDDEBUG
|
||||
|
||||
if (clnp_ours(&isoa)) {
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_update_srcrt: updating src rt\n");
|
||||
ENDDEBUG
|
||||
|
||||
/* update pointer to next src route */
|
||||
len++; /* count length byte too! */
|
||||
CLNPSRCRT_OFF(oidx, options) += len;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_dooptions
|
||||
*
|
||||
* PURPOSE: Process options accompanying a clnp datagram.
|
||||
* Processing includes
|
||||
* - log our address if recording route
|
||||
*
|
||||
* RETURNS: none
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
clnp_dooptions(options, oidx, ifp, isoa)
|
||||
struct mbuf *options; /* ptr to options mbuf */
|
||||
struct clnp_optidx *oidx; /* ptr to option index */
|
||||
struct ifnet *ifp; /* ptr to interface pkt is leaving on */
|
||||
struct iso_addr *isoa; /* ptr to our address for this ifp */
|
||||
{
|
||||
/*
|
||||
* If record route is specified, move all
|
||||
* existing records over, and insert the address of
|
||||
* interface passed
|
||||
*/
|
||||
if (oidx->cni_recrtp) {
|
||||
char *opt; /* ptr to beginning of recrt option */
|
||||
u_char off; /* offset from opt of first free byte */
|
||||
char *rec_start; /* beginning of new rt recorded */
|
||||
|
||||
opt = CLNP_OFFTOOPT(options, oidx->cni_recrtp);
|
||||
off = *(opt + 1);
|
||||
rec_start = opt + off - 1;
|
||||
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_dooptions: record route: option x%x for %d bytes\n",
|
||||
opt, oidx->cni_recrt_len);
|
||||
printf("\tfree slot offset x%x\n", off);
|
||||
printf("clnp_dooptions: recording %s\n", clnp_iso_addrp(isoa));
|
||||
printf("clnp_dooptions: option dump:\n");
|
||||
dump_buf(opt, oidx->cni_recrt_len);
|
||||
ENDDEBUG
|
||||
|
||||
/* proceed only if recording has not been terminated */
|
||||
if (off != 0xff) {
|
||||
int new_addrlen = isoa->isoa_len + 1;
|
||||
/*
|
||||
* if there is insufficient room to store the next address,
|
||||
* then terminate recording. Plus 1 on isoa_len is for the
|
||||
* length byte itself
|
||||
*/
|
||||
if (oidx->cni_recrt_len - (off - 1) < new_addrlen) {
|
||||
*(opt + 1) = 0xff; /* terminate recording */
|
||||
} else {
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_dooptions: new addr at x%x for %d\n",
|
||||
rec_start, new_addrlen);
|
||||
ENDDEBUG
|
||||
|
||||
bcopy((caddr_t)isoa, rec_start, new_addrlen);
|
||||
|
||||
/* update offset field */
|
||||
*(opt + 1) += new_addrlen;
|
||||
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_dooptions: new option dump:\n");
|
||||
dump_buf(opt, oidx->cni_recrt_len);
|
||||
ENDDEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_set_opts
|
||||
*
|
||||
* PURPOSE: Check the data mbuf passed for option sanity. If it is
|
||||
* ok, then set the options ptr to address the data mbuf.
|
||||
* If an options mbuf exists, free it. This implies that
|
||||
* any old options will be lost. If data is NULL, simply
|
||||
* free any old options.
|
||||
*
|
||||
* RETURNS: unix error code
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
clnp_set_opts(options, data)
|
||||
struct mbuf **options; /* target for option information */
|
||||
struct mbuf **data; /* source of option information */
|
||||
{
|
||||
int error = 0; /* error return value */
|
||||
struct clnp_optidx dummy; /* dummy index - not used */
|
||||
|
||||
/*
|
||||
* remove any existing options
|
||||
*/
|
||||
if (*options != NULL) {
|
||||
m_freem(*options);
|
||||
*options = NULL;
|
||||
}
|
||||
|
||||
if (*data != NULL) {
|
||||
/*
|
||||
* Insure that the options are reasonable.
|
||||
*
|
||||
* Also, we do not support security, priority,
|
||||
* nor do we allow one to send an ER option
|
||||
*
|
||||
* The QOS parameter is checked for the DECBIT.
|
||||
*/
|
||||
if ((clnp_opt_sanity(*data, mtod(*data, caddr_t), (*data)->m_len,
|
||||
&dummy) != 0) ||
|
||||
(dummy.cni_securep) ||
|
||||
(dummy.cni_priorp) ||
|
||||
(dummy.cni_er_reason != ER_INVALREAS)) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
*options = *data;
|
||||
*data = NULL; /* so caller won't free mbuf @ *data */
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_opt_sanity
|
||||
*
|
||||
* PURPOSE: Check the options (beginning at opts for len bytes) for
|
||||
* sanity. In addition, fill in the option index structure
|
||||
* in with information about each option discovered.
|
||||
*
|
||||
* RETURNS: success (options check out) - 0
|
||||
* failure - an ER pdu error code describing failure
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: Each pointer field of the option index is filled in with
|
||||
* the offset from the beginning of the mbuf data, not the
|
||||
* actual address.
|
||||
*/
|
||||
clnp_opt_sanity(m, opts, len, oidx)
|
||||
struct mbuf *m; /* mbuf options reside in */
|
||||
caddr_t opts; /* ptr to buffer containing options */
|
||||
int len; /* length of buffer */
|
||||
struct clnp_optidx *oidx; /* RETURN: filled in with option idx info */
|
||||
{
|
||||
u_char opcode; /* code of particular option */
|
||||
u_char oplen; /* length of a particular option */
|
||||
caddr_t opts_end; /* ptr to end of options */
|
||||
u_char pad = 0, secure = 0, srcrt = 0, recrt = 0, qos = 0, prior = 0;
|
||||
/* flags for catching duplicate options */
|
||||
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_opt_sanity: checking %d bytes of data:\n", len);
|
||||
dump_buf(opts, len);
|
||||
ENDDEBUG
|
||||
|
||||
/* clear option index field if passed */
|
||||
bzero((caddr_t)oidx, sizeof(struct clnp_optidx));
|
||||
|
||||
/*
|
||||
* We need to indicate whether the ER option is present. This is done
|
||||
* by overloading the er_reason field to also indicate presense of
|
||||
* the option along with the option value. I would like ER_INVALREAS
|
||||
* to have value 0, but alas, 0 is a valid er reason...
|
||||
*/
|
||||
oidx->cni_er_reason = ER_INVALREAS;
|
||||
|
||||
opts_end = opts + len;
|
||||
while (opts < opts_end) {
|
||||
/* must have at least 2 bytes per option (opcode and len) */
|
||||
if (opts + 2 > opts_end)
|
||||
return(GEN_INCOMPLETE);
|
||||
|
||||
opcode = *opts++;
|
||||
oplen = *opts++;
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_opt_sanity: opcode is %x and oplen %d\n",
|
||||
opcode, oplen);
|
||||
printf("clnp_opt_sanity: clnpoval_SRCRT is %x\n", CLNPOVAL_SRCRT);
|
||||
|
||||
switch (opcode) {
|
||||
case CLNPOVAL_PAD: {
|
||||
printf("CLNPOVAL_PAD\n");
|
||||
} break;
|
||||
case CLNPOVAL_SECURE: {
|
||||
printf("CLNPOVAL_SECURE\n");
|
||||
} break;
|
||||
case CLNPOVAL_SRCRT: {
|
||||
printf("CLNPOVAL_SRCRT\n");
|
||||
} break;
|
||||
case CLNPOVAL_RECRT: {
|
||||
printf("CLNPOVAL_RECRT\n");
|
||||
} break;
|
||||
case CLNPOVAL_QOS: {
|
||||
printf("CLNPOVAL_QOS\n");
|
||||
} break;
|
||||
case CLNPOVAL_PRIOR: {
|
||||
printf("CLNPOVAL_PRIOR\n");
|
||||
} break;
|
||||
case CLNPOVAL_ERREAS: {
|
||||
printf("CLNPOVAL_ERREAS\n");
|
||||
} break;
|
||||
default:
|
||||
printf("UKNOWN option %x\n", opcode);
|
||||
}
|
||||
ENDDEBUG
|
||||
|
||||
/* don't allow crazy length values */
|
||||
if (opts + oplen > opts_end)
|
||||
return(GEN_INCOMPLETE);
|
||||
|
||||
switch (opcode) {
|
||||
case CLNPOVAL_PAD:
|
||||
/*
|
||||
* Padding: increment pointer by length of padding
|
||||
*/
|
||||
if (pad++) /* duplicate ? */
|
||||
return(GEN_DUPOPT);
|
||||
opts += oplen;
|
||||
break;
|
||||
|
||||
case CLNPOVAL_SECURE: {
|
||||
u_char format = *opts;
|
||||
|
||||
if (secure++) /* duplicate ? */
|
||||
return(GEN_DUPOPT);
|
||||
/*
|
||||
* Security: high 2 bits of first octet indicate format
|
||||
* (00 in high bits is reserved).
|
||||
* Remaining bits must be 0. Remaining octets indicate
|
||||
* actual security
|
||||
*/
|
||||
if (((format & 0x3f) > 0) || /* low 6 bits set ? */
|
||||
((format & 0xc0) == 0)) /* high 2 bits zero ? */
|
||||
return(GEN_HDRSYNTAX);
|
||||
|
||||
oidx->cni_securep = CLNP_OPTTOOFF(m, opts);
|
||||
oidx->cni_secure_len = oplen;
|
||||
opts += oplen;
|
||||
} break;
|
||||
|
||||
case CLNPOVAL_SRCRT: {
|
||||
u_char type, offset; /* type of rt, offset of start */
|
||||
caddr_t route_end; /* address of end of route option */
|
||||
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_opt_sanity: SRC RT\n");
|
||||
ENDDEBUG
|
||||
|
||||
if (srcrt++) /* duplicate ? */
|
||||
return(GEN_DUPOPT);
|
||||
/*
|
||||
* source route: There must be 2 bytes following the length
|
||||
* field: type and offset. The type must be either
|
||||
* partial route or complete route. The offset field must
|
||||
* be within the option. A single exception is made, however.
|
||||
* The offset may be 1 greater than the length. This case
|
||||
* occurs when the last source route record is consumed.
|
||||
* In this case, we ignore the source route option.
|
||||
* RAH? You should be able to set offset to 'ff' like in record
|
||||
* route!
|
||||
* Following this is a series of address fields.
|
||||
* Each address field is composed of a (length, address) pair.
|
||||
* Insure that the offset and each address length is reasonable
|
||||
*/
|
||||
route_end = opts + oplen;
|
||||
|
||||
if (opts + 2 > route_end)
|
||||
return(SRCRT_SYNTAX);
|
||||
|
||||
type = *opts;
|
||||
offset = *(opts+1);
|
||||
|
||||
|
||||
/* type must be partial or complete */
|
||||
if (!((type == CLNPOVAL_PARTRT) || (type == CLNPOVAL_COMPRT)))
|
||||
return(SRCRT_SYNTAX);
|
||||
|
||||
oidx->cni_srcrt_s = CLNP_OPTTOOFF(m, opts);
|
||||
oidx->cni_srcrt_len = oplen;
|
||||
|
||||
opts += offset-1; /*set opts to first addr in rt */
|
||||
|
||||
/*
|
||||
* Offset must be reasonable:
|
||||
* less than end of options, or equal to end of options
|
||||
*/
|
||||
if (opts >= route_end) {
|
||||
if (opts == route_end) {
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_opt_sanity: end of src route info\n");
|
||||
ENDDEBUG
|
||||
break;
|
||||
} else
|
||||
return(SRCRT_SYNTAX);
|
||||
}
|
||||
|
||||
while (opts < route_end) {
|
||||
u_char addrlen = *opts++;
|
||||
if (opts + addrlen > route_end)
|
||||
return(SRCRT_SYNTAX);
|
||||
opts += addrlen;
|
||||
}
|
||||
} break;
|
||||
case CLNPOVAL_RECRT: {
|
||||
u_char type, offset; /* type of rt, offset of start */
|
||||
caddr_t record_end; /* address of end of record option */
|
||||
|
||||
if (recrt++) /* duplicate ? */
|
||||
return(GEN_DUPOPT);
|
||||
/*
|
||||
* record route: after the length field, expect a
|
||||
* type and offset. Type must be partial or complete.
|
||||
* Offset indicates where to start recording. Insure it
|
||||
* is within the option. All ones for offset means
|
||||
* recording is terminated.
|
||||
*/
|
||||
record_end = opts + oplen;
|
||||
|
||||
oidx->cni_recrtp = CLNP_OPTTOOFF(m, opts);
|
||||
oidx->cni_recrt_len = oplen;
|
||||
|
||||
if (opts + 2 > record_end)
|
||||
return(GEN_INCOMPLETE);
|
||||
|
||||
type = *opts;
|
||||
offset = *(opts+1);
|
||||
|
||||
/* type must be partial or complete */
|
||||
if (!((type == CLNPOVAL_PARTRT) || (type == CLNPOVAL_COMPRT)))
|
||||
return(GEN_HDRSYNTAX);
|
||||
|
||||
/* offset must be reasonable */
|
||||
if ((offset < 0xff) && (opts + offset > record_end))
|
||||
return(GEN_HDRSYNTAX);
|
||||
opts += oplen;
|
||||
} break;
|
||||
case CLNPOVAL_QOS: {
|
||||
u_char format = *opts;
|
||||
|
||||
if (qos++) /* duplicate ? */
|
||||
return(GEN_DUPOPT);
|
||||
/*
|
||||
* qos: high 2 bits of first octet indicate format
|
||||
* (00 in high bits is reserved).
|
||||
* Remaining bits must be 0 (unless format indicates
|
||||
* globally unique qos, in which case remaining bits indicate
|
||||
* qos (except bit 6 which is reserved)). Otherwise,
|
||||
* remaining octets indicate actual qos.
|
||||
*/
|
||||
if (((format & 0xc0) == 0) || /* high 2 bits zero ? */
|
||||
(((format & 0xc0) != CLNPOVAL_GLOBAL) &&
|
||||
((format & 0x3f) > 0))) /* not global,low bits used ? */
|
||||
return(GEN_HDRSYNTAX);
|
||||
|
||||
oidx->cni_qos_formatp = CLNP_OPTTOOFF(m, opts);
|
||||
oidx->cni_qos_len = oplen;
|
||||
|
||||
opts += oplen;
|
||||
} break;
|
||||
|
||||
case CLNPOVAL_PRIOR: {
|
||||
if (prior++) /* duplicate ? */
|
||||
return(GEN_DUPOPT);
|
||||
/*
|
||||
* priority: value must be one byte long
|
||||
*/
|
||||
if (oplen != 1)
|
||||
return(GEN_HDRSYNTAX);
|
||||
|
||||
oidx->cni_priorp = CLNP_OPTTOOFF(m, opts);
|
||||
|
||||
opts += oplen;
|
||||
} break;
|
||||
|
||||
case CLNPOVAL_ERREAS: {
|
||||
/*
|
||||
* er reason: value must be two bytes long
|
||||
*/
|
||||
if (oplen != 2)
|
||||
return(GEN_HDRSYNTAX);
|
||||
|
||||
oidx->cni_er_reason = *opts;
|
||||
|
||||
opts += oplen;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_opt_sanity: UNKNOWN OPTION 0x%x\n", opcode);
|
||||
ENDDEBUG
|
||||
return(DISC_UNSUPPOPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_opt_sanity: return(0)\n", opcode);
|
||||
ENDDEBUG
|
||||
return(0);
|
||||
}
|
||||
#endif /* ISO */
|
||||
@@ -1,563 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp_output.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnp_output.c,v 1.3 1994/11/15 14:26:12 bde Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp_output.c,v 1.3 1994/11/15 14:26:12 bde Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp_output.c,v $ */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/iso_pcb.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/clnp_stat.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
|
||||
static struct clnp_fixed dt_template = {
|
||||
ISO8473_CLNP, /* network identifier */
|
||||
0, /* length */
|
||||
ISO8473_V1, /* version */
|
||||
CLNP_TTL, /* ttl */
|
||||
CLNP_DT|CNF_SEG_OK|CNF_ERR_OK, /* type */
|
||||
0, /* segment length */
|
||||
0 /* checksum */
|
||||
};
|
||||
|
||||
static struct clnp_fixed raw_template = {
|
||||
ISO8473_CLNP, /* network identifier */
|
||||
0, /* length */
|
||||
ISO8473_V1, /* version */
|
||||
CLNP_TTL, /* ttl */
|
||||
CLNP_RAW|CNF_SEG_OK|CNF_ERR_OK, /* type */
|
||||
0, /* segment length */
|
||||
0 /* checksum */
|
||||
};
|
||||
|
||||
static struct clnp_fixed echo_template = {
|
||||
ISO8473_CLNP, /* network identifier */
|
||||
0, /* length */
|
||||
ISO8473_V1, /* version */
|
||||
CLNP_TTL, /* ttl */
|
||||
CLNP_EC|CNF_SEG_OK|CNF_ERR_OK, /* type */
|
||||
0, /* segment length */
|
||||
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 */
|
||||
|
||||
int clnp_id = 0; /* id for segmented dgrams */
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_output
|
||||
*
|
||||
* PURPOSE: output the data in the mbuf as a clnp datagram
|
||||
*
|
||||
* The data specified by m0 is sent as a clnp datagram.
|
||||
* The mbuf chain m0 will be freed when this routine has
|
||||
* returned.
|
||||
*
|
||||
* If options is non-null, it points to an mbuf which contains
|
||||
* options to be sent with the datagram. The options must
|
||||
* be formatted in the mbuf according to clnp rules. Options
|
||||
* will not be freed.
|
||||
*
|
||||
* Datalen specifies the length of the data in m0.
|
||||
*
|
||||
* Src and dst are the addresses for the packet.
|
||||
*
|
||||
* If route is non-null, it is used as the route for
|
||||
* the packet.
|
||||
*
|
||||
* By default, a DT is sent. However, if flags & CNLP_SEND_ER
|
||||
* then an ER will be sent. If flags & CLNP_SEND_RAW, then
|
||||
* the packet will be send as raw clnp.
|
||||
*
|
||||
* RETURNS: 0 success
|
||||
* appropriate error code
|
||||
*
|
||||
* SIDE EFFECTS: none
|
||||
*
|
||||
* NOTES:
|
||||
* Flags are interpretated as follows:
|
||||
* CLNP_NO_SEG - do not allow this pkt to be segmented.
|
||||
* CLNP_NO_ER - have pkt request ER suppression.
|
||||
* CLNP_SEND_RAW - send pkt as RAW DT rather than TP DT
|
||||
* CLNP_NO_CKSUM - don't compute clnp checksum
|
||||
* CLNP_ECHO - send as ECHO packet
|
||||
*
|
||||
* When checking for a cached packet, clnp checks
|
||||
* that the route taken is still up. It does not
|
||||
* check that the route is still to the same destination.
|
||||
* This means that any entity that alters an existing
|
||||
* route for an isopcb (such as when a redirect arrives)
|
||||
* must invalidate the clnp cache. It might be perferable
|
||||
* to have clnp check that the route has the same dest, but
|
||||
* by avoiding this check, we save a call to iso_addrmatch1.
|
||||
*/
|
||||
clnp_output(m0, isop, datalen, flags)
|
||||
struct mbuf *m0; /* data for the packet */
|
||||
struct isopcb *isop; /* iso pcb */
|
||||
int datalen; /* number of bytes of data in m0 */
|
||||
int flags; /* flags */
|
||||
{
|
||||
int error = 0; /* return value of function */
|
||||
register struct mbuf *m = m0; /* mbuf for clnp header chain */
|
||||
register struct clnp_fixed *clnp; /* ptr to fixed part of hdr */
|
||||
register caddr_t hoff; /* offset into header */
|
||||
int total_len; /* total length of packet */
|
||||
struct iso_addr *src; /* ptr to source address */
|
||||
struct iso_addr *dst; /* ptr to destination address */
|
||||
struct clnp_cache clc; /* storage for cache information */
|
||||
struct clnp_cache *clcp = NULL; /* ptr to clc */
|
||||
int hdrlen = 0;
|
||||
|
||||
dst = &isop->isop_faddr->siso_addr;
|
||||
if (isop->isop_laddr == 0) {
|
||||
struct iso_ifaddr *ia = 0;
|
||||
clnp_route(dst, &isop->isop_route, flags, 0, &ia);
|
||||
if (ia == 0 || ia->ia_ifa.ifa_addr->sa_family != AF_ISO)
|
||||
return (ENETUNREACH);
|
||||
src = &ia->ia_addr.siso_addr;
|
||||
} else
|
||||
src = &isop->isop_laddr->siso_addr;
|
||||
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: to %s", clnp_iso_addrp(dst));
|
||||
printf(" from %s of %d bytes\n", clnp_iso_addrp(src), datalen);
|
||||
printf("\toptions x%x, flags x%x, isop_clnpcache x%x\n",
|
||||
isop->isop_options, flags, isop->isop_clnpcache);
|
||||
ENDDEBUG
|
||||
|
||||
if (isop->isop_clnpcache != NULL) {
|
||||
clcp = mtod(isop->isop_clnpcache, struct clnp_cache *);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if cache is valid ...
|
||||
*/
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: ck cache: clcp %x\n", clcp);
|
||||
if (clcp != NULL) {
|
||||
printf("\tclc_dst %s\n", clnp_iso_addrp(&clcp->clc_dst));
|
||||
printf("\tisop_opts x%x, clc_opts x%x\n", isop->isop_options,
|
||||
clcp->clc_options);
|
||||
if (isop->isop_route.ro_rt)
|
||||
printf("\tro_rt x%x, rt_flags x%x\n",
|
||||
isop->isop_route.ro_rt, isop->isop_route.ro_rt->rt_flags);
|
||||
printf("\tflags x%x, clc_flags x%x\n", flags, clcp->clc_flags);
|
||||
printf("\tclc_hdr x%x\n", clcp->clc_hdr);
|
||||
}
|
||||
ENDDEBUG
|
||||
if ((clcp != NULL) && /* cache exists */
|
||||
(isop->isop_options == clcp->clc_options) && /* same options */
|
||||
(iso_addrmatch1(dst, &clcp->clc_dst)) && /* dst still same */
|
||||
(isop->isop_route.ro_rt != NULL) && /* route exists */
|
||||
(isop->isop_route.ro_rt == clcp->clc_rt) && /* and is cached */
|
||||
(isop->isop_route.ro_rt->rt_flags & RTF_UP) && /* route still up */
|
||||
(flags == clcp->clc_flags) && /* same flags */
|
||||
(clcp->clc_hdr != NULL)) { /* hdr mbuf exists */
|
||||
/*
|
||||
* The cache is valid
|
||||
*/
|
||||
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: using cache\n");
|
||||
ENDDEBUG
|
||||
|
||||
m = m_copy(clcp->clc_hdr, 0, (int)M_COPYALL);
|
||||
if (m == NULL) {
|
||||
/*
|
||||
* No buffers left to copy cached packet header. Use
|
||||
* the cached packet header this time, and
|
||||
* mark the hdr as vacant
|
||||
*/
|
||||
m = clcp->clc_hdr;
|
||||
clcp->clc_hdr = NULL;
|
||||
}
|
||||
m->m_next = m0; /* ASSUMES pkt hdr is 1 mbuf long */
|
||||
clnp = mtod(m, struct clnp_fixed *);
|
||||
} else {
|
||||
struct clnp_optidx *oidx = NULL; /* index to clnp options */
|
||||
|
||||
/*
|
||||
* The cache is not valid. Allocate an mbuf (if necessary)
|
||||
* to hold cached info. If one is not available, then
|
||||
* don't bother with the cache
|
||||
*/
|
||||
INCSTAT(cns_cachemiss);
|
||||
if (flags & CLNP_NOCACHE) {
|
||||
clcp = &clc;
|
||||
} else {
|
||||
if (isop->isop_clnpcache == NULL) {
|
||||
/*
|
||||
* There is no clnpcache. Allocate an mbuf to hold one
|
||||
*/
|
||||
if ((isop->isop_clnpcache = m_get(M_DONTWAIT, MT_HEADER))
|
||||
== NULL) {
|
||||
/*
|
||||
* No mbufs available. Pretend that we don't want
|
||||
* caching this time.
|
||||
*/
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: no mbufs to allocate to cache\n");
|
||||
ENDDEBUG
|
||||
flags |= CLNP_NOCACHE;
|
||||
clcp = &clc;
|
||||
} else {
|
||||
clcp = mtod(isop->isop_clnpcache, struct clnp_cache *);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* A clnpcache mbuf exists. If the clc_hdr is not null,
|
||||
* we must free it, as a new one is about to be created.
|
||||
*/
|
||||
clcp = mtod(isop->isop_clnpcache, struct clnp_cache *);
|
||||
if (clcp->clc_hdr != NULL) {
|
||||
/*
|
||||
* The clc_hdr is not null but a clnpcache mbuf exists.
|
||||
* This means that there was a cache, but the existing
|
||||
* copy of the hdr is no longer valid. Free it now
|
||||
* before we lose the pointer to it.
|
||||
*/
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: freeing old clc_hdr 0x%x\n",
|
||||
clcp->clc_hdr);
|
||||
ENDDEBUG
|
||||
m_free(clcp->clc_hdr);
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: freed old clc_hdr (done)\n");
|
||||
ENDDEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: NEW clcp x%x\n",clcp);
|
||||
ENDDEBUG
|
||||
bzero((caddr_t)clcp, sizeof(struct clnp_cache));
|
||||
|
||||
if (isop->isop_optindex)
|
||||
oidx = mtod(isop->isop_optindex, struct clnp_optidx *);
|
||||
|
||||
/*
|
||||
* Don't allow packets with security, quality of service,
|
||||
* priority, or error report options to be sent.
|
||||
*/
|
||||
if ((isop->isop_options) && (oidx)) {
|
||||
if ((oidx->cni_securep) ||
|
||||
(oidx->cni_priorp) ||
|
||||
(oidx->cni_qos_formatp) ||
|
||||
(oidx->cni_er_reason != ER_INVALREAS)) {
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: pkt dropped - option unsupported\n");
|
||||
ENDDEBUG
|
||||
m_freem(m0);
|
||||
return(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't allow any invalid flags to be set
|
||||
*/
|
||||
if ((flags & (CLNP_VFLAGS)) != flags) {
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: packet dropped - flags unsupported\n");
|
||||
ENDDEBUG
|
||||
INCSTAT(cns_odropped);
|
||||
m_freem(m0);
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't allow funny lengths on dst; src may be zero in which
|
||||
* case we insert the source address based upon the interface
|
||||
*/
|
||||
if ((src->isoa_len > sizeof(struct iso_addr)) ||
|
||||
(dst->isoa_len == 0) ||
|
||||
(dst->isoa_len > sizeof(struct iso_addr))) {
|
||||
m_freem(m0);
|
||||
INCSTAT(cns_odropped);
|
||||
return(ENAMETOOLONG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Grab mbuf to contain header
|
||||
*/
|
||||
MGETHDR(m, M_DONTWAIT, MT_HEADER);
|
||||
if (m == 0) {
|
||||
m_freem(m0);
|
||||
INCSTAT(cns_odropped);
|
||||
return(ENOBUFS);
|
||||
}
|
||||
INCSTAT(cns_sent);
|
||||
m->m_next = m0;
|
||||
clnp = mtod(m, struct clnp_fixed *);
|
||||
clcp->clc_segoff = 0;
|
||||
|
||||
/*
|
||||
* Fill in all of fixed hdr except lengths and checksum
|
||||
*/
|
||||
if (flags & CLNP_SEND_RAW) {
|
||||
*clnp = raw_template;
|
||||
} else if (flags & CLNP_ECHO) {
|
||||
*clnp = echo_template;
|
||||
} else if (flags & CLNP_ECHOR) {
|
||||
*clnp = echor_template;
|
||||
} else {
|
||||
*clnp = dt_template;
|
||||
}
|
||||
if (flags & CLNP_NO_SEG)
|
||||
clnp->cnf_type &= ~CNF_SEG_OK;
|
||||
if (flags & CLNP_NO_ER)
|
||||
clnp->cnf_type &= ~CNF_ERR_OK;
|
||||
|
||||
/*
|
||||
* Route packet; special case for source rt
|
||||
*/
|
||||
if ((isop->isop_options) && CLNPSRCRT_VALID(oidx)) {
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: calling clnp_srcroute\n");
|
||||
ENDDEBUG
|
||||
error = clnp_srcroute(isop->isop_options, oidx, &isop->isop_route,
|
||||
&clcp->clc_firsthop, &clcp->clc_ifa, dst);
|
||||
} else {
|
||||
IFDEBUG(D_OUTPUT)
|
||||
ENDDEBUG
|
||||
error = clnp_route(dst, &isop->isop_route, flags,
|
||||
&clcp->clc_firsthop, &clcp->clc_ifa);
|
||||
}
|
||||
if (error || (clcp->clc_ifa == 0)) {
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: route failed, errno %d\n", error);
|
||||
printf("@clcp:\n");
|
||||
dump_buf(clcp, sizeof (struct clnp_cache));
|
||||
ENDDEBUG
|
||||
goto bad;
|
||||
}
|
||||
clcp->clc_rt = isop->isop_route.ro_rt; /* XXX */
|
||||
clcp->clc_ifp = clcp->clc_ifa->ia_ifp; /* XXX */
|
||||
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: packet routed to %s\n",
|
||||
clnp_iso_addrp(
|
||||
&((struct sockaddr_iso *)clcp->clc_firsthop)->siso_addr));
|
||||
ENDDEBUG
|
||||
|
||||
/*
|
||||
* If src address is not yet specified, use address of
|
||||
* interface. NOTE: this will now update the laddr field in
|
||||
* the isopcb. Is this desirable? RAH?
|
||||
*/
|
||||
if (src->isoa_len == 0) {
|
||||
src = &(clcp->clc_ifa->ia_addr.siso_addr);
|
||||
IFDEBUG(D_OUTPUT)
|
||||
printf("clnp_output: new src %s\n", clnp_iso_addrp(src));
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the source and destination address,
|
||||
*/
|
||||
hoff = (caddr_t)clnp + sizeof(struct clnp_fixed);
|
||||
CLNP_INSERT_ADDR(hoff, *dst);
|
||||
CLNP_INSERT_ADDR(hoff, *src);
|
||||
|
||||
/*
|
||||
* Leave room for the segment part, if segmenting is selected
|
||||
*/
|
||||
if (clnp->cnf_type & CNF_SEG_OK) {
|
||||
clcp->clc_segoff = hoff - (caddr_t)clnp;
|
||||
hoff += sizeof(struct clnp_segment);
|
||||
}
|
||||
|
||||
clnp->cnf_hdr_len = m->m_len = (u_char)(hoff - (caddr_t)clnp);
|
||||
hdrlen = clnp->cnf_hdr_len;
|
||||
|
||||
#ifdef DECBIT
|
||||
/*
|
||||
* Add the globally unique QOS (with room for congestion experienced
|
||||
* bit). I can safely assume that this option is not in the options
|
||||
* mbuf below because I checked that the option was not specified
|
||||
* previously
|
||||
*/
|
||||
if ((m->m_len + sizeof(qos_option)) < MLEN) {
|
||||
bcopy((caddr_t)qos_option, hoff, sizeof(qos_option));
|
||||
clnp->cnf_hdr_len += sizeof(qos_option);
|
||||
hdrlen += sizeof(qos_option);
|
||||
m->m_len += sizeof(qos_option);
|
||||
}
|
||||
#endif /* DECBIT */
|
||||
|
||||
/*
|
||||
* If an options mbuf is present, concatenate a copy to the hdr mbuf.
|
||||
*/
|
||||
if (isop->isop_options) {
|
||||
struct mbuf *opt_copy = m_copy(isop->isop_options, 0, (int)M_COPYALL);
|
||||
if (opt_copy == NULL) {
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
}
|
||||
/* Link in place */
|
||||
opt_copy->m_next = m->m_next;
|
||||
m->m_next = opt_copy;
|
||||
|
||||
/* update size of header */
|
||||
clnp->cnf_hdr_len += opt_copy->m_len;
|
||||
hdrlen += opt_copy->m_len;
|
||||
}
|
||||
|
||||
if (hdrlen > CLNP_HDR_MAX) {
|
||||
error = EMSGSIZE;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now set up the cache entry in the pcb
|
||||
*/
|
||||
if ((flags & CLNP_NOCACHE) == 0) {
|
||||
if (clcp->clc_hdr = m_copy(m, 0, (int)clnp->cnf_hdr_len)) {
|
||||
clcp->clc_dst = *dst;
|
||||
clcp->clc_flags = flags;
|
||||
clcp->clc_options = isop->isop_options;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If small enough for interface, send directly
|
||||
* Fill in segmentation part of hdr if using the full protocol
|
||||
*/
|
||||
total_len = clnp->cnf_hdr_len + datalen;
|
||||
if (clnp->cnf_type & CNF_SEG_OK) {
|
||||
struct clnp_segment seg_part; /* segment part of hdr */
|
||||
seg_part.cng_id = htons(clnp_id++);
|
||||
seg_part.cng_off = htons(0);
|
||||
seg_part.cng_tot_len = htons(total_len);
|
||||
(void) bcopy((caddr_t)&seg_part, (caddr_t) clnp + clcp->clc_segoff,
|
||||
sizeof(seg_part));
|
||||
}
|
||||
if (total_len <= SN_MTU(clcp->clc_ifp, clcp->clc_rt)) {
|
||||
HTOC(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, total_len);
|
||||
m->m_pkthdr.len = total_len;
|
||||
/*
|
||||
* Compute clnp checksum (on header only)
|
||||
*/
|
||||
if (flags & CLNP_NO_CKSUM) {
|
||||
HTOC(clnp->cnf_cksum_msb, clnp->cnf_cksum_lsb, 0);
|
||||
} else {
|
||||
iso_gen_csum(m, CLNP_CKSUM_OFF, (int)clnp->cnf_hdr_len);
|
||||
}
|
||||
|
||||
IFDEBUG(D_DUMPOUT)
|
||||
struct mbuf *mdump = m;
|
||||
printf("clnp_output: sending dg:\n");
|
||||
while (mdump != NULL) {
|
||||
dump_buf(mtod(mdump, caddr_t), mdump->m_len);
|
||||
mdump = mdump->m_next;
|
||||
}
|
||||
ENDDEBUG
|
||||
|
||||
error = SN_OUTPUT(clcp, m);
|
||||
goto done;
|
||||
} else {
|
||||
/*
|
||||
* Too large for interface; fragment if possible.
|
||||
*/
|
||||
error = clnp_fragment(clcp->clc_ifp, m, clcp->clc_firsthop,
|
||||
total_len, clcp->clc_segoff, flags, clcp->clc_rt);
|
||||
goto done;
|
||||
}
|
||||
bad:
|
||||
m_freem(m);
|
||||
done:
|
||||
if (error) {
|
||||
clnp_stat.cns_sent--;
|
||||
clnp_stat.cns_odropped++;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int clnp_ctloutput()
|
||||
{
|
||||
}
|
||||
@@ -1,353 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp_raw.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnp_raw.c,v 1.2 1994/08/02 07:49:44 davidg Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp_raw.c,v 1.2 1994/08/02 07:49:44 davidg Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp_raw.c,v $ */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <net/raw_cb.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_pcb.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/clnp_stat.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
|
||||
#include <netiso/tp_user.h> /* XXX -- defines SOL_NETWORK */
|
||||
|
||||
struct sockproto rclnp_proto = { PF_ISO, 0 };
|
||||
/*
|
||||
* FUNCTION: rclnp_input
|
||||
*
|
||||
* PURPOSE: Setup generic address an protocol structures for
|
||||
* raw input routine, then pass them along with the
|
||||
* mbuf chain.
|
||||
*
|
||||
* RETURNS: none
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: The protocol field of rclnp_proto is set to zero indicating
|
||||
* no protocol.
|
||||
*/
|
||||
rclnp_input(m, src, dst, hdrlen)
|
||||
struct mbuf *m; /* ptr to packet */
|
||||
struct sockaddr_iso *src; /* ptr to src address */
|
||||
struct sockaddr_iso *dst; /* ptr to dest address */
|
||||
int hdrlen; /* length (in bytes) of clnp header */
|
||||
{
|
||||
#ifdef TROLL
|
||||
if (trollctl.tr_ops & TR_CHUCK) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
#endif /* TROLL */
|
||||
|
||||
raw_input(m, &rclnp_proto, (struct sockaddr *)src, (struct sockaddr *)dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: rclnp_output
|
||||
*
|
||||
* PURPOSE: Prepare to send a raw clnp packet. Setup src and dest
|
||||
* addresses, count the number of bytes to send, and
|
||||
* call clnp_output.
|
||||
*
|
||||
* RETURNS: success - 0
|
||||
* failure - an appropriate error code
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
rclnp_output(m0, so)
|
||||
struct mbuf *m0; /* packet to send */
|
||||
struct socket *so; /* socket to send from */
|
||||
{
|
||||
register struct mbuf *m; /* used to scan a chain */
|
||||
int len = 0; /* store length of chain here */
|
||||
struct rawisopcb *rp = sotorawisopcb(so); /* ptr to raw cb */
|
||||
int error; /* return value of function */
|
||||
int flags; /* flags for clnp_output */
|
||||
|
||||
if (0 == (m0->m_flags & M_PKTHDR))
|
||||
return (EINVAL);
|
||||
/*
|
||||
* Set up src address. If user has bound socket to an address, use it.
|
||||
* Otherwise, do not specify src (clnp_output will fill it in).
|
||||
*/
|
||||
if (rp->risop_rcb.rcb_laddr) {
|
||||
if (rp->risop_isop.isop_sladdr.siso_family != AF_ISO) {
|
||||
bad:
|
||||
m_freem(m0);
|
||||
return(EAFNOSUPPORT);
|
||||
}
|
||||
}
|
||||
/* set up dest address */
|
||||
if (rp->risop_rcb.rcb_faddr == 0)
|
||||
goto bad;
|
||||
rp->risop_isop.isop_sfaddr =
|
||||
*(struct sockaddr_iso *)rp->risop_rcb.rcb_faddr;
|
||||
rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr;
|
||||
|
||||
/* get flags and ship it off */
|
||||
flags = rp->risop_flags & CLNP_VFLAGS;
|
||||
|
||||
error = clnp_output(m0, &rp->risop_isop, m0->m_pkthdr.len,
|
||||
flags|CLNP_NOCACHE);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: rclnp_ctloutput
|
||||
*
|
||||
* PURPOSE: Raw clnp socket option processing
|
||||
* All options are stored inside an mbuf.
|
||||
*
|
||||
* RETURNS: success - 0
|
||||
* failure - unix error code
|
||||
*
|
||||
* SIDE EFFECTS: If the options mbuf does not exist, it the mbuf passed
|
||||
* is used.
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
rclnp_ctloutput(op, so, level, optname, m)
|
||||
int op; /* type of operation */
|
||||
struct socket *so; /* ptr to socket */
|
||||
int level; /* level of option */
|
||||
int optname; /* name of option */
|
||||
struct mbuf **m; /* ptr to ptr to option data */
|
||||
{
|
||||
int error = 0;
|
||||
register struct rawisopcb *rp = sotorawisopcb(so);/* raw cb ptr */
|
||||
|
||||
IFDEBUG(D_CTLOUTPUT)
|
||||
printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n",
|
||||
op, level, optname);
|
||||
if (*m != NULL) {
|
||||
printf("rclnp_ctloutput: %d bytes of mbuf data\n", (*m)->m_len);
|
||||
dump_buf(mtod((*m), caddr_t), (*m)->m_len);
|
||||
}
|
||||
ENDDEBUG
|
||||
|
||||
#ifdef SOL_NETWORK
|
||||
if (level != SOL_NETWORK)
|
||||
error = EINVAL;
|
||||
else switch (op) {
|
||||
#else
|
||||
switch (op) {
|
||||
#endif /* SOL_NETWORK */
|
||||
case PRCO_SETOPT:
|
||||
switch (optname) {
|
||||
case CLNPOPT_FLAGS: {
|
||||
u_short usr_flags;
|
||||
/*
|
||||
* Insure that the data passed has exactly one short in it
|
||||
*/
|
||||
if ((*m == NULL) || ((*m)->m_len != sizeof(short))) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't allow invalid flags to be set
|
||||
*/
|
||||
usr_flags = (*mtod((*m), short *));
|
||||
|
||||
if ((usr_flags & (CLNP_VFLAGS)) != usr_flags) {
|
||||
error = EINVAL;
|
||||
} else
|
||||
rp->risop_flags |= usr_flags;
|
||||
|
||||
} break;
|
||||
|
||||
case CLNPOPT_OPTS:
|
||||
if (error = clnp_set_opts(&rp->risop_isop.isop_options, m))
|
||||
break;
|
||||
rp->risop_isop.isop_optindex = m_get(M_WAIT, MT_SOOPTS);
|
||||
(void) clnp_opt_sanity(rp->risop_isop.isop_options,
|
||||
mtod(rp->risop_isop.isop_options, caddr_t),
|
||||
rp->risop_isop.isop_options->m_len,
|
||||
mtod(rp->risop_isop.isop_optindex,
|
||||
struct clnp_optidx *));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PRCO_GETOPT:
|
||||
#ifdef notdef
|
||||
/* commented out to keep hi C quiet */
|
||||
switch (optname) {
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
#endif /* notdef */
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (op == PRCO_SETOPT) {
|
||||
/* note: m_freem does not barf is *m is NULL */
|
||||
m_freem(*m);
|
||||
*m = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
clnp_usrreq(so, req, m, nam, control)
|
||||
register struct socket *so;
|
||||
int req;
|
||||
struct mbuf *m, *nam, *control;
|
||||
{
|
||||
register int error = 0;
|
||||
register struct rawisopcb *rp = sotorawisopcb(so);
|
||||
|
||||
rp = sotorawisopcb(so);
|
||||
switch (req) {
|
||||
|
||||
case PRU_ATTACH:
|
||||
if (rp)
|
||||
panic("rip_attach");
|
||||
MALLOC(rp, struct rawisopcb *, sizeof *rp, M_PCB, M_WAITOK);
|
||||
if (rp == 0)
|
||||
return (ENOBUFS);
|
||||
bzero((caddr_t)rp, sizeof *rp);
|
||||
so->so_pcb = (caddr_t)rp;
|
||||
break;
|
||||
|
||||
case PRU_DETACH:
|
||||
if (rp == 0)
|
||||
panic("rip_detach");
|
||||
if (rp->risop_isop.isop_options)
|
||||
m_freem(rp->risop_isop.isop_options);
|
||||
if (rp->risop_isop.isop_route.ro_rt)
|
||||
RTFREE(rp->risop_isop.isop_route.ro_rt);
|
||||
if (rp->risop_rcb.rcb_laddr)
|
||||
rp->risop_rcb.rcb_laddr = 0;
|
||||
/* free clnp cached hdr if necessary */
|
||||
if (rp->risop_isop.isop_clnpcache != NULL) {
|
||||
struct clnp_cache *clcp =
|
||||
mtod(rp->risop_isop.isop_clnpcache, struct clnp_cache *);
|
||||
if (clcp->clc_hdr != NULL) {
|
||||
m_free(clcp->clc_hdr);
|
||||
}
|
||||
m_free(rp->risop_isop.isop_clnpcache);
|
||||
}
|
||||
if (rp->risop_isop.isop_optindex != NULL)
|
||||
m_free(rp->risop_isop.isop_optindex);
|
||||
|
||||
break;
|
||||
|
||||
case PRU_BIND:
|
||||
{
|
||||
struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
|
||||
|
||||
if (nam->m_len != sizeof(*addr))
|
||||
return (EINVAL);
|
||||
if ((ifnet == 0) ||
|
||||
(addr->siso_family != AF_ISO) ||
|
||||
(addr->siso_addr.isoa_len &&
|
||||
ifa_ifwithaddr((struct sockaddr *)addr) == 0))
|
||||
return (EADDRNOTAVAIL);
|
||||
rp->risop_isop.isop_sladdr = *addr;
|
||||
rp->risop_rcb.rcb_laddr = (struct sockaddr *)
|
||||
(rp->risop_isop.isop_laddr = &rp->risop_isop.isop_sladdr);
|
||||
return (0);
|
||||
}
|
||||
case PRU_CONNECT:
|
||||
{
|
||||
struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
|
||||
|
||||
if ((nam->m_len > sizeof(*addr)) || (addr->siso_len > sizeof(*addr)))
|
||||
return (EINVAL);
|
||||
if (ifnet == 0)
|
||||
return (EADDRNOTAVAIL);
|
||||
if (addr->siso_family != AF_ISO)
|
||||
rp->risop_isop.isop_sfaddr = *addr;
|
||||
rp->risop_rcb.rcb_faddr = (struct sockaddr *)
|
||||
(rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr);
|
||||
soisconnected(so);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
error = raw_usrreq(so, req, m, nam, control);
|
||||
|
||||
if (error && req == PRU_ATTACH && so->so_pcb)
|
||||
free((caddr_t)rp, M_PCB);
|
||||
return (error);
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp_stat.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnp_stat.h,v 1.3 1994/08/21 06:14:13 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_CLNP_STAT_H_
|
||||
#define _NETISO_CLNP_STAT_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp_stat.h,v 1.3 1994/08/21 06:14:13 paul Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp_stat.h,v $ */
|
||||
|
||||
struct clnp_stat {
|
||||
int cns_total; /* total pkts received */
|
||||
int cns_toosmall; /* fixed part of header too small */
|
||||
int cns_badhlen; /* header length is not reasonable */
|
||||
int cns_badcsum; /* checksum on packet failed */
|
||||
int cns_badaddr; /* address fields were not reasonable */
|
||||
int cns_badvers; /* incorrect version */
|
||||
int cns_noseg; /* segment information forgotten */
|
||||
int cns_noproto; /* incorrect protocol id */
|
||||
int cns_delivered; /* packets consumed by protocol */
|
||||
int cns_ttlexpired; /* ttl has expired */
|
||||
int cns_forward; /* forwarded packets */
|
||||
int cns_sent; /* total packets sent */
|
||||
int cns_odropped; /* o.k. packets discarded, e.g. ENOBUFS */
|
||||
int cns_cantforward; /* non-forwarded packets */
|
||||
int cns_fragmented; /* packets fragmented */
|
||||
int cns_fragments; /* fragments received */
|
||||
int cns_fragdropped; /* fragments discarded */
|
||||
int cns_fragtimeout; /* fragments timed out */
|
||||
int cns_ofragments; /* fragments generated */
|
||||
int cns_cantfrag; /* fragmentation prohibited */
|
||||
int cns_reassembled; /* packets reconstructed */
|
||||
int cns_cachemiss; /* cache misses */
|
||||
int cns_congest_set; /* congestion experienced bit set */
|
||||
int cns_congest_rcvd; /* congestion experienced bit received */
|
||||
int cns_er_inhist[CLNP_ERRORS + 1];
|
||||
int cns_er_outhist[CLNP_ERRORS + 1];
|
||||
} clnp_stat ;
|
||||
|
||||
#ifdef INCSTAT
|
||||
#undef INCSTAT
|
||||
#endif /* INCSTAT */
|
||||
#define INCSTAT(x) clnp_stat./**/x/**/++
|
||||
|
||||
#endif
|
||||
@@ -1,659 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp_subr.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnp_subr.c,v 1.2 1994/08/02 07:49:50 davidg Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp_subr.c,v 1.2 1994/08/02 07:49:50 davidg Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp_subr.c,v $ */
|
||||
|
||||
#ifdef ISO
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/iso_pcb.h>
|
||||
#include <netiso/iso_snpac.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/clnp_stat.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_data_ck
|
||||
*
|
||||
* PURPOSE: Check that the amount of data in the mbuf chain is
|
||||
* at least as much as the clnp header would have us
|
||||
* expect. Trim mbufs if longer than expected, drop
|
||||
* packet if shorter than expected.
|
||||
*
|
||||
* RETURNS: success - ptr to mbuf chain
|
||||
* failure - 0
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
struct mbuf *
|
||||
clnp_data_ck(m, length)
|
||||
register struct mbuf *m; /* ptr to mbuf chain containing hdr & data */
|
||||
int length; /* length (in bytes) of packet */
|
||||
{
|
||||
register int len; /* length of data */
|
||||
register struct mbuf *mhead; /* ptr to head of chain */
|
||||
|
||||
len = -length;
|
||||
mhead = m;
|
||||
for (;;) {
|
||||
len += m->m_len;
|
||||
if (m->m_next == 0)
|
||||
break;
|
||||
m = m->m_next;
|
||||
}
|
||||
if (len != 0) {
|
||||
if (len < 0) {
|
||||
INCSTAT(cns_toosmall);
|
||||
clnp_discard(mhead, GEN_INCOMPLETE);
|
||||
return 0;
|
||||
}
|
||||
if (len <= m->m_len)
|
||||
m->m_len -= len;
|
||||
else
|
||||
m_adj(mhead, -len);
|
||||
}
|
||||
return mhead;
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* FUNCTION: clnp_extract_addr
|
||||
*
|
||||
* PURPOSE: Extract the source and destination address from the
|
||||
* supplied buffer. Place them in the supplied address buffers.
|
||||
* If insufficient data is supplied, then fail.
|
||||
*
|
||||
* RETURNS: success - Address of first byte in the packet past
|
||||
* the address part.
|
||||
* failure - 0
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
caddr_t
|
||||
clnp_extract_addr(bufp, buflen, srcp, destp)
|
||||
caddr_t bufp; /* ptr to buffer containing addresses */
|
||||
int buflen; /* length of buffer */
|
||||
register struct iso_addr *srcp; /* ptr to source address buffer */
|
||||
register struct iso_addr *destp; /* ptr to destination address buffer */
|
||||
{
|
||||
int len; /* argument to bcopy */
|
||||
|
||||
/*
|
||||
* check that we have enough data. Plus1 is for length octet
|
||||
*/
|
||||
if ((u_char)*bufp + 1 > buflen) {
|
||||
return((caddr_t)0);
|
||||
}
|
||||
len = destp->isoa_len = (u_char)*bufp++;
|
||||
(void) bcopy(bufp, (caddr_t)destp, len);
|
||||
buflen -= len;
|
||||
bufp += len;
|
||||
|
||||
/*
|
||||
* check that we have enough data. Plus1 is for length octet
|
||||
*/
|
||||
if ((u_char)*bufp + 1 > buflen) {
|
||||
return((caddr_t)0);
|
||||
}
|
||||
len = srcp->isoa_len = (u_char)* bufp++;
|
||||
(void) bcopy(bufp, (caddr_t)srcp, len);
|
||||
bufp += len;
|
||||
|
||||
/*
|
||||
* Insure that the addresses make sense
|
||||
*/
|
||||
if (iso_ck_addr(srcp) && iso_ck_addr(destp))
|
||||
return bufp;
|
||||
else
|
||||
return (caddr_t) 0;
|
||||
}
|
||||
#endif /* notdef */
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_ours
|
||||
*
|
||||
* PURPOSE: Decide whether the supplied packet is destined for
|
||||
* us, or that it should be forwarded on.
|
||||
*
|
||||
* RETURNS: packet is for us - 1
|
||||
* packet is not for us - 0
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
clnp_ours(dst)
|
||||
register struct iso_addr *dst; /* ptr to destination address */
|
||||
{
|
||||
register struct iso_ifaddr *ia; /* scan through interface addresses */
|
||||
|
||||
for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf("clnp_ours: ia_sis x%x, dst x%x\n", &ia->ia_addr,
|
||||
dst);
|
||||
ENDDEBUG
|
||||
/*
|
||||
* XXX Warning:
|
||||
* We are overloading siso_tlen in the if's address, as an nsel length.
|
||||
*/
|
||||
if (dst->isoa_len == ia->ia_addr.siso_nlen &&
|
||||
bcmp((caddr_t)ia->ia_addr.siso_addr.isoa_genaddr,
|
||||
(caddr_t)dst->isoa_genaddr,
|
||||
ia->ia_addr.siso_nlen - ia->ia_addr.siso_tlen) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Dec bit set if ifp qlen is greater than congest_threshold */
|
||||
int congest_threshold = 0;
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_forward
|
||||
*
|
||||
* PURPOSE: Forward the datagram passed
|
||||
* clnpintr guarantees that the header will be
|
||||
* contigious (a cluster mbuf will be used if necessary).
|
||||
*
|
||||
* If oidx is NULL, no options are present.
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
clnp_forward(m, len, dst, oidx, seg_off, inbound_shp)
|
||||
struct mbuf *m; /* pkt to forward */
|
||||
int len; /* length of pkt */
|
||||
struct iso_addr *dst; /* destination address */
|
||||
struct clnp_optidx *oidx; /* option index */
|
||||
int seg_off;/* offset of segmentation part */
|
||||
struct snpa_hdr *inbound_shp; /* subnetwork header of inbound packet */
|
||||
{
|
||||
struct clnp_fixed *clnp; /* ptr to fixed part of header */
|
||||
int error; /* return value of route function */
|
||||
struct sockaddr *next_hop; /* next hop for dgram */
|
||||
struct ifnet *ifp; /* ptr to outgoing interface */
|
||||
struct iso_ifaddr *ia = 0;/* ptr to iso name for ifp */
|
||||
struct route_iso route; /* filled in by clnp_route */
|
||||
extern int iso_systype;
|
||||
|
||||
clnp = mtod(m, struct clnp_fixed *);
|
||||
bzero((caddr_t)&route, sizeof(route)); /* MUST be done before "bad:" */
|
||||
|
||||
/*
|
||||
* Don't forward multicast or broadcast packets
|
||||
*/
|
||||
if ((inbound_shp) && (IS_MULTICAST(inbound_shp->snh_dhost))) {
|
||||
IFDEBUG(D_FORWARD)
|
||||
printf("clnp_forward: dropping multicast packet\n");
|
||||
ENDDEBUG
|
||||
clnp->cnf_type &= ~CNF_ERR_OK; /* so we don't generate an ER */
|
||||
clnp_discard(m, 0);
|
||||
INCSTAT(cns_cantforward);
|
||||
goto done;
|
||||
}
|
||||
|
||||
IFDEBUG(D_FORWARD)
|
||||
printf("clnp_forward: %d bytes, to %s, options x%x\n", len,
|
||||
clnp_iso_addrp(dst), oidx);
|
||||
ENDDEBUG
|
||||
|
||||
/*
|
||||
* Decrement ttl, and if zero drop datagram
|
||||
* Can't compare ttl as less than zero 'cause its a unsigned
|
||||
*/
|
||||
if ((clnp->cnf_ttl == 0) || (--clnp->cnf_ttl == 0)) {
|
||||
IFDEBUG(D_FORWARD)
|
||||
printf("clnp_forward: discarding datagram because ttl is zero\n");
|
||||
ENDDEBUG
|
||||
INCSTAT(cns_ttlexpired);
|
||||
clnp_discard(m, TTL_EXPTRANSIT);
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
* Route packet; special case for source rt
|
||||
*/
|
||||
if CLNPSRCRT_VALID(oidx) {
|
||||
/*
|
||||
* Update src route first
|
||||
*/
|
||||
clnp_update_srcrt(m, oidx);
|
||||
error = clnp_srcroute(m, oidx, &route, &next_hop, &ia, dst);
|
||||
} else {
|
||||
error = clnp_route(dst, &route, 0, &next_hop, &ia);
|
||||
}
|
||||
if (error || ia == 0) {
|
||||
IFDEBUG(D_FORWARD)
|
||||
printf("clnp_forward: can't route packet (errno %d)\n", error);
|
||||
ENDDEBUG
|
||||
clnp_discard(m, ADDR_DESTUNREACH);
|
||||
INCSTAT(cns_cantforward);
|
||||
goto done;
|
||||
}
|
||||
ifp = ia->ia_ifp;
|
||||
|
||||
IFDEBUG(D_FORWARD)
|
||||
printf("clnp_forward: packet routed to %s\n",
|
||||
clnp_iso_addrp(&((struct sockaddr_iso *)next_hop)->siso_addr));
|
||||
ENDDEBUG
|
||||
|
||||
INCSTAT(cns_forward);
|
||||
|
||||
/*
|
||||
* If we are an intermediate system and
|
||||
* we are routing outbound on the same ifp that the packet
|
||||
* arrived upon, and we know the next hop snpa,
|
||||
* then generate a redirect request
|
||||
*/
|
||||
if ((iso_systype & SNPA_IS) && (inbound_shp) &&
|
||||
(ifp == inbound_shp->snh_ifp))
|
||||
esis_rdoutput(inbound_shp, m, oidx, dst, route.ro_rt);
|
||||
/*
|
||||
* If options are present, update them
|
||||
*/
|
||||
if (oidx) {
|
||||
struct iso_addr *mysrc = &ia->ia_addr.siso_addr;
|
||||
if (mysrc == NULL) {
|
||||
clnp_discard(m, ADDR_DESTUNREACH);
|
||||
INCSTAT(cns_cantforward);
|
||||
clnp_stat.cns_forward--;
|
||||
goto done;
|
||||
} else {
|
||||
(void) clnp_dooptions(m, oidx, ifp, mysrc);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DECBIT
|
||||
if (ifp->if_snd.ifq_len > congest_threshold) {
|
||||
/*
|
||||
* Congestion! Set the Dec Bit and thank Dave Oran
|
||||
*/
|
||||
IFDEBUG(D_FORWARD)
|
||||
printf("clnp_forward: congestion experienced\n");
|
||||
ENDDEBUG
|
||||
if ((oidx) && (oidx->cni_qos_formatp)) {
|
||||
caddr_t qosp = CLNP_OFFTOOPT(m, oidx->cni_qos_formatp);
|
||||
u_char qos = *qosp;
|
||||
IFDEBUG(D_FORWARD)
|
||||
printf("clnp_forward: setting congestion bit (qos x%x)\n", qos);
|
||||
ENDDEBUG
|
||||
if ((qos & CLNPOVAL_GLOBAL) == CLNPOVAL_GLOBAL) {
|
||||
qos |= CLNPOVAL_CONGESTED;
|
||||
INCSTAT(cns_congest_set);
|
||||
*qosp = qos;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DECBIT */
|
||||
|
||||
/*
|
||||
* Dispatch the datagram if it is small enough, otherwise fragment
|
||||
*/
|
||||
if (len <= SN_MTU(ifp, route.ro_rt)) {
|
||||
iso_gen_csum(m, CLNP_CKSUM_OFF, (int)clnp->cnf_hdr_len);
|
||||
(void) (*ifp->if_output)(ifp, m, next_hop, route.ro_rt);
|
||||
} else {
|
||||
(void) clnp_fragment(ifp, m, next_hop, len, seg_off, /* flags */0, route.ro_rt);
|
||||
}
|
||||
|
||||
done:
|
||||
/*
|
||||
* Free route
|
||||
*/
|
||||
if (route.ro_rt != NULL) {
|
||||
RTFREE(route.ro_rt);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* FUNCTION: clnp_insert_addr
|
||||
*
|
||||
* PURPOSE: Insert the address part into a clnp datagram.
|
||||
*
|
||||
* RETURNS: Address of first byte after address part in datagram.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: Assume that there is enough space for the address part.
|
||||
*/
|
||||
caddr_t
|
||||
clnp_insert_addr(bufp, srcp, dstp)
|
||||
caddr_t bufp; /* address of where addr part goes */
|
||||
register struct iso_addr *srcp; /* ptr to src addr */
|
||||
register struct iso_addr *dstp; /* ptr to dst addr */
|
||||
{
|
||||
*bufp++ = dstp->isoa_len;
|
||||
(void) bcopy((caddr_t)dstp, bufp, dstp->isoa_len);
|
||||
bufp += dstp->isoa_len;
|
||||
|
||||
*bufp++ = srcp->isoa_len;
|
||||
(void) bcopy((caddr_t)srcp, bufp, srcp->isoa_len);
|
||||
bufp += srcp->isoa_len;
|
||||
|
||||
return bufp;
|
||||
}
|
||||
|
||||
#endif /* notdef */
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_route
|
||||
*
|
||||
* PURPOSE: Route a clnp datagram to the first hop toward its
|
||||
* destination. In many cases, the first hop will be
|
||||
* the destination. The address of a route
|
||||
* is specified. If a routing entry is present in
|
||||
* that route, and it is still up to the same destination,
|
||||
* then no further action is necessary. Otherwise, a
|
||||
* new routing entry will be allocated.
|
||||
*
|
||||
* RETURNS: route found - 0
|
||||
* unix error code
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: It is up to the caller to free the routing entry
|
||||
* allocated in route.
|
||||
*/
|
||||
clnp_route(dst, ro, flags, first_hop, ifa)
|
||||
struct iso_addr *dst; /* ptr to datagram destination */
|
||||
register struct route_iso *ro; /* existing route structure */
|
||||
int flags; /* flags for routing */
|
||||
struct sockaddr **first_hop; /* result: fill in with ptr to firsthop */
|
||||
struct iso_ifaddr **ifa; /* result: fill in with ptr to interface */
|
||||
{
|
||||
if (flags & SO_DONTROUTE) {
|
||||
struct iso_ifaddr *ia;
|
||||
|
||||
if (ro->ro_rt) {
|
||||
RTFREE(ro->ro_rt);
|
||||
ro->ro_rt = 0;
|
||||
}
|
||||
bzero((caddr_t)&ro->ro_dst, sizeof(ro->ro_dst));
|
||||
bcopy((caddr_t)dst, (caddr_t)&ro->ro_dst.siso_addr,
|
||||
1 + (unsigned)dst->isoa_len);
|
||||
ro->ro_dst.siso_family = AF_ISO;
|
||||
ro->ro_dst.siso_len = sizeof(ro->ro_dst);
|
||||
ia = iso_localifa(&ro->ro_dst);
|
||||
if (ia == 0)
|
||||
return EADDRNOTAVAIL;
|
||||
if (ifa)
|
||||
*ifa = ia;
|
||||
if (first_hop)
|
||||
*first_hop = (struct sockaddr *)&ro->ro_dst;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* If there is a cached route, check that it is still up and to
|
||||
* the same destination. If not, free it and try again.
|
||||
*/
|
||||
if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
|
||||
(Bcmp(ro->ro_dst.siso_data, dst->isoa_genaddr, dst->isoa_len)))) {
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf("clnp_route: freeing old route: ro->ro_rt 0x%x\n",
|
||||
ro->ro_rt);
|
||||
printf("clnp_route: old route refcnt: 0x%x\n",
|
||||
ro->ro_rt->rt_refcnt);
|
||||
ENDDEBUG
|
||||
|
||||
/* free old route entry */
|
||||
RTFREE(ro->ro_rt);
|
||||
ro->ro_rt = (struct rtentry *)0;
|
||||
} else {
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf("clnp_route: OK route exists\n");
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
if (ro->ro_rt == 0) {
|
||||
/* set up new route structure */
|
||||
bzero((caddr_t)&ro->ro_dst, sizeof(ro->ro_dst));
|
||||
ro->ro_dst.siso_len = sizeof(ro->ro_dst);
|
||||
ro->ro_dst.siso_family = AF_ISO;
|
||||
Bcopy(dst, &ro->ro_dst.siso_addr, 1 + dst->isoa_len);
|
||||
/* allocate new route */
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf("clnp_route: allocating new route to %s\n",
|
||||
clnp_iso_addrp(dst));
|
||||
ENDDEBUG
|
||||
rtalloc((struct route *)ro);
|
||||
}
|
||||
if (ro->ro_rt == 0)
|
||||
return(ENETUNREACH); /* rtalloc failed */
|
||||
ro->ro_rt->rt_use++;
|
||||
if (ifa)
|
||||
if ((*ifa = (struct iso_ifaddr *)ro->ro_rt->rt_ifa) == 0)
|
||||
panic("clnp_route");
|
||||
if (first_hop) {
|
||||
if (ro->ro_rt->rt_flags & RTF_GATEWAY)
|
||||
*first_hop = ro->ro_rt->rt_gateway;
|
||||
else
|
||||
*first_hop = (struct sockaddr *)&ro->ro_dst;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_srcroute
|
||||
*
|
||||
* PURPOSE: Source route the datagram. If complete source
|
||||
* routing is specified but not possible, then
|
||||
* return an error. If src routing is terminated, then
|
||||
* try routing on destination.
|
||||
* Usage of first_hop,
|
||||
* ifp, and error return is identical to clnp_route.
|
||||
*
|
||||
* RETURNS: 0 or unix error code
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: Remember that option index pointers are really
|
||||
* offsets from the beginning of the mbuf.
|
||||
*/
|
||||
clnp_srcroute(options, oidx, ro, first_hop, ifa, final_dst)
|
||||
struct mbuf *options; /* ptr to options */
|
||||
struct clnp_optidx *oidx; /* index to options */
|
||||
struct route_iso *ro; /* route structure */
|
||||
struct sockaddr **first_hop; /* RETURN: fill in with ptr to firsthop */
|
||||
struct iso_ifaddr **ifa; /* RETURN: fill in with ptr to interface */
|
||||
struct iso_addr *final_dst; /* final destination */
|
||||
{
|
||||
struct iso_addr dst; /* first hop specified by src rt */
|
||||
int error = 0; /* return code */
|
||||
|
||||
/*
|
||||
* Check if we have run out of routes
|
||||
* If so, then try to route on destination.
|
||||
*/
|
||||
if CLNPSRCRT_TERM(oidx, options) {
|
||||
dst.isoa_len = final_dst->isoa_len;
|
||||
bcopy(final_dst->isoa_genaddr, dst.isoa_genaddr, dst.isoa_len);
|
||||
} else {
|
||||
/*
|
||||
* setup dst based on src rt specified
|
||||
*/
|
||||
dst.isoa_len = CLNPSRCRT_CLEN(oidx, options);
|
||||
bcopy(CLNPSRCRT_CADDR(oidx, options), dst.isoa_genaddr, dst.isoa_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* try to route it
|
||||
*/
|
||||
error = clnp_route(&dst, ro, 0, first_hop, ifa);
|
||||
if (error != 0)
|
||||
return error;
|
||||
|
||||
/*
|
||||
* If complete src rt, first hop must be equal to dst
|
||||
*/
|
||||
if ((CLNPSRCRT_TYPE(oidx, options) == CLNPOVAL_COMPRT) &&
|
||||
(!iso_addrmatch1(&(*(struct sockaddr_iso **)first_hop)->siso_addr,&dst))){
|
||||
IFDEBUG(D_OPTIONS)
|
||||
printf("clnp_srcroute: complete src route failed\n");
|
||||
ENDDEBUG
|
||||
return EHOSTUNREACH; /* RAH? would like ESRCRTFAILED */
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
* PURPOSE: print notice of route with mtu not initialized.
|
||||
*
|
||||
* RETURNS: mtu of ifp.
|
||||
*
|
||||
* SIDE EFFECTS: prints notice, slows down system.
|
||||
*/
|
||||
clnp_badmtu(ifp, rt, line, file)
|
||||
struct ifnet *ifp; /* outgoing interface */
|
||||
struct rtentry *rt; /* dst route */
|
||||
int line; /* where the dirty deed occured */
|
||||
char *file; /* where the dirty deed occured */
|
||||
{
|
||||
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 ");
|
||||
dump_isoaddr(rt_key(rt));
|
||||
#endif
|
||||
return ifp->if_mtu;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_ypocb - backwards bcopy
|
||||
*
|
||||
* PURPOSE: bcopy starting at end of src rather than beginning.
|
||||
*
|
||||
* RETURNS: none
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: No attempt has been made to make this efficient
|
||||
*/
|
||||
clnp_ypocb(from, to, len)
|
||||
caddr_t from; /* src buffer */
|
||||
caddr_t to; /* dst buffer */
|
||||
u_int len; /* number of bytes */
|
||||
{
|
||||
while (len--)
|
||||
*(to + len) = *(from + len);
|
||||
}
|
||||
#endif /* ISO */
|
||||
@@ -1,182 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)clnp_timer.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: clnp_timer.c,v 1.3 1994/11/15 14:26:13 bde Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/clnp_timer.c,v 1.3 1994/11/15 14:26:13 bde Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/clnp_timer.c,v $ */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/clnp_stat.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
|
||||
extern struct clnp_fragl *clnp_frags;
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_freefrags
|
||||
*
|
||||
* PURPOSE: Free the resources associated with a fragment
|
||||
*
|
||||
* RETURNS: pointer to next fragment in list of fragments
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
* TODO: send ER back to source
|
||||
*/
|
||||
struct clnp_fragl *
|
||||
clnp_freefrags(cfh)
|
||||
register struct clnp_fragl *cfh; /* fragment header to delete */
|
||||
{
|
||||
struct clnp_fragl *next = cfh->cfl_next;
|
||||
struct clnp_frag *cf;
|
||||
|
||||
/* free any frags hanging around */
|
||||
cf = cfh->cfl_frags;
|
||||
while (cf != NULL) {
|
||||
struct clnp_frag *cf_next = cf->cfr_next;
|
||||
INCSTAT(cns_fragdropped);
|
||||
m_freem(cf->cfr_data);
|
||||
cf = cf_next;
|
||||
}
|
||||
|
||||
/* free the copy of the header */
|
||||
INCSTAT(cns_fragdropped);
|
||||
m_freem(cfh->cfl_orighdr);
|
||||
|
||||
if (clnp_frags == cfh) {
|
||||
clnp_frags = cfh->cfl_next;
|
||||
} else {
|
||||
struct clnp_fragl *scan;
|
||||
|
||||
for (scan = clnp_frags; scan != NULL; scan = scan->cfl_next) {
|
||||
if (scan->cfl_next == cfh) {
|
||||
scan->cfl_next = cfh->cfl_next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free the fragment header */
|
||||
m_freem(dtom(cfh));
|
||||
|
||||
return(next);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_slowtimo
|
||||
*
|
||||
* PURPOSE: clnp timer processing; if the ttl expires on a
|
||||
* packet on the reassembly queue, discard it.
|
||||
*
|
||||
* RETURNS: none
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
clnp_slowtimo()
|
||||
{
|
||||
register struct clnp_fragl *cfh = clnp_frags;
|
||||
int s = splnet();
|
||||
|
||||
while (cfh != NULL) {
|
||||
if (--cfh->cfl_ttl == 0) {
|
||||
cfh = clnp_freefrags(cfh);
|
||||
INCSTAT(cns_fragtimeout);
|
||||
} else {
|
||||
cfh = cfh->cfl_next;
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: clnp_drain
|
||||
*
|
||||
* PURPOSE: drain off all datagram fragments
|
||||
*
|
||||
* RETURNS: none
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
* TODO: should send back ER
|
||||
*/
|
||||
clnp_drain()
|
||||
{
|
||||
register struct clnp_fragl *cfh = clnp_frags;
|
||||
|
||||
while (cfh != NULL)
|
||||
cfh = clnp_freefrags(cfh);
|
||||
}
|
||||
@@ -1,407 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* @(#)cltp_usrreq.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: cltp_usrreq.c,v 1.3 1994/11/15 14:26:14 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef CLTPOVAL_SRC /* XXX -- till files gets changed */
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_pcb.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/cltp_var.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CLTP protocol implementation.
|
||||
* Per ISO 8602, December, 1987.
|
||||
*/
|
||||
cltp_init()
|
||||
{
|
||||
|
||||
cltb.isop_next = cltb.isop_prev = &cltb;
|
||||
}
|
||||
|
||||
int cltp_cksum = 1;
|
||||
|
||||
|
||||
/* ARGUSED */
|
||||
cltp_input(m0, srcsa, dstsa, cons_channel, output)
|
||||
struct mbuf *m0;
|
||||
struct sockaddr *srcsa, *dstsa;
|
||||
u_int cons_channel;
|
||||
int (*output)();
|
||||
{
|
||||
register struct isopcb *isop;
|
||||
register struct mbuf *m = m0;
|
||||
register u_char *up = mtod(m, u_char *);
|
||||
register struct sockaddr_iso *src = (struct sockaddr_iso *)srcsa;
|
||||
int len, hdrlen = *up + 1, dlen = 0;
|
||||
u_char *uplim = up + hdrlen;
|
||||
caddr_t dtsap;
|
||||
|
||||
for (len = 0; m; m = m->m_next)
|
||||
len += m->m_len;
|
||||
up += 2; /* skip header */
|
||||
while (up < uplim) switch (*up) { /* process options */
|
||||
case CLTPOVAL_SRC:
|
||||
src->siso_tlen = up[1];
|
||||
src->siso_len = up[1] + TSEL(src) - (caddr_t)src;
|
||||
if (src->siso_len < sizeof(*src))
|
||||
src->siso_len = sizeof(*src);
|
||||
else if (src->siso_len > sizeof(*src)) {
|
||||
MGET(m, M_DONTWAIT, MT_SONAME);
|
||||
if (m == 0)
|
||||
goto bad;
|
||||
m->m_len = src->siso_len;
|
||||
src = mtod(m, struct sockaddr_iso *);
|
||||
bcopy((caddr_t)srcsa, (caddr_t)src, srcsa->sa_len);
|
||||
}
|
||||
bcopy((caddr_t)up + 2, TSEL(src), up[1]);
|
||||
up += 2 + src->siso_tlen;
|
||||
continue;
|
||||
|
||||
case CLTPOVAL_DST:
|
||||
dtsap = 2 + (caddr_t)up;
|
||||
dlen = up[1];
|
||||
up += 2 + dlen;
|
||||
continue;
|
||||
|
||||
case CLTPOVAL_CSM:
|
||||
if (iso_check_csum(m0, len)) {
|
||||
cltpstat.cltps_badsum++;
|
||||
goto bad;
|
||||
}
|
||||
up += 4;
|
||||
continue;
|
||||
|
||||
default:
|
||||
printf("clts: unknown option (%x)\n", up[0]);
|
||||
cltpstat.cltps_hdrops++;
|
||||
goto bad;
|
||||
}
|
||||
if (dlen == 0 || src->siso_tlen == 0)
|
||||
goto bad;
|
||||
for (isop = cltb.isop_next;; isop = isop->isop_next) {
|
||||
if (isop == &cltb) {
|
||||
cltpstat.cltps_noport++;
|
||||
goto bad;
|
||||
}
|
||||
if (isop->isop_laddr &&
|
||||
bcmp(TSEL(isop->isop_laddr), dtsap, dlen) == 0)
|
||||
break;
|
||||
}
|
||||
m = m0;
|
||||
m->m_len -= hdrlen;
|
||||
m->m_data += hdrlen;
|
||||
if (sbappendaddr(&isop->isop_socket->so_rcv, (struct sockaddr *)src,
|
||||
m, (struct mbuf *)0) == 0)
|
||||
goto bad;
|
||||
cltpstat.cltps_ipackets++;
|
||||
sorwakeup(isop->isop_socket);
|
||||
m0 = 0;
|
||||
bad:
|
||||
if (src != (struct sockaddr_iso *)srcsa)
|
||||
m_freem(dtom(src));
|
||||
if (m0)
|
||||
m_freem(m0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify a cltp user of an asynchronous error;
|
||||
* just wake up so that he can collect error status.
|
||||
*/
|
||||
cltp_notify(isop)
|
||||
register struct isopcb *isop;
|
||||
{
|
||||
|
||||
sorwakeup(isop->isop_socket);
|
||||
sowwakeup(isop->isop_socket);
|
||||
}
|
||||
|
||||
cltp_ctlinput(cmd, sa)
|
||||
int cmd;
|
||||
struct sockaddr *sa;
|
||||
{
|
||||
extern u_char inetctlerrmap[];
|
||||
struct sockaddr_iso *siso;
|
||||
int iso_rtchange();
|
||||
|
||||
if ((unsigned)cmd > PRC_NCMDS)
|
||||
return;
|
||||
if (sa->sa_family != AF_ISO && sa->sa_family != AF_CCITT)
|
||||
return;
|
||||
siso = (struct sockaddr_iso *)sa;
|
||||
if (siso == 0 || siso->siso_nlen == 0)
|
||||
return;
|
||||
|
||||
switch (cmd) {
|
||||
case PRC_ROUTEDEAD:
|
||||
case PRC_REDIRECT_NET:
|
||||
case PRC_REDIRECT_HOST:
|
||||
case PRC_REDIRECT_TOSNET:
|
||||
case PRC_REDIRECT_TOSHOST:
|
||||
iso_pcbnotify(&cltb, siso,
|
||||
(int)inetctlerrmap[cmd], iso_rtchange);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (inetctlerrmap[cmd] == 0)
|
||||
return; /* XXX */
|
||||
iso_pcbnotify(&cltb, siso, (int)inetctlerrmap[cmd],
|
||||
cltp_notify);
|
||||
}
|
||||
}
|
||||
|
||||
cltp_output(isop, m)
|
||||
register struct isopcb *isop;
|
||||
register struct mbuf *m;
|
||||
{
|
||||
register int len;
|
||||
register struct sockaddr_iso *siso;
|
||||
int hdrlen, error = 0, docsum;
|
||||
register u_char *up;
|
||||
|
||||
if (isop->isop_laddr == 0 || isop->isop_faddr == 0) {
|
||||
error = ENOTCONN;
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* Calculate data length and get a mbuf for CLTP header.
|
||||
*/
|
||||
hdrlen = 2 + 2 + isop->isop_laddr->siso_tlen
|
||||
+ 2 + isop->isop_faddr->siso_tlen;
|
||||
if (docsum = /*isop->isop_flags & CLNP_NO_CKSUM*/ cltp_cksum)
|
||||
hdrlen += 4;
|
||||
M_PREPEND(m, hdrlen, M_WAIT);
|
||||
len = m->m_pkthdr.len;
|
||||
/*
|
||||
* Fill in mbuf with extended CLTP header
|
||||
*/
|
||||
up = mtod(m, u_char *);
|
||||
up[0] = hdrlen - 1;
|
||||
up[1] = UD_TPDU_type;
|
||||
up[2] = CLTPOVAL_SRC;
|
||||
up[3] = (siso = isop->isop_laddr)->siso_tlen;
|
||||
up += 4;
|
||||
bcopy(TSEL(siso), (caddr_t)up, siso->siso_tlen);
|
||||
up += siso->siso_tlen;
|
||||
up[0] = CLTPOVAL_DST;
|
||||
up[1] = (siso = isop->isop_faddr)->siso_tlen;
|
||||
up += 2;
|
||||
bcopy(TSEL(siso), (caddr_t)up, siso->siso_tlen);
|
||||
/*
|
||||
* Stuff checksum and output datagram.
|
||||
*/
|
||||
if (docsum) {
|
||||
up += siso->siso_tlen;
|
||||
up[0] = CLTPOVAL_CSM;
|
||||
up[1] = 2;
|
||||
iso_gen_csum(m, 2 + up - mtod(m, u_char *), len);
|
||||
}
|
||||
cltpstat.cltps_opackets++;
|
||||
return (tpclnp_output(isop, m, len, !docsum));
|
||||
bad:
|
||||
m_freem(m);
|
||||
return (error);
|
||||
}
|
||||
|
||||
u_long cltp_sendspace = 9216; /* really max datagram size */
|
||||
u_long cltp_recvspace = 40 * (1024 + sizeof(struct sockaddr_iso));
|
||||
/* 40 1K datagrams */
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
cltp_usrreq(so, req, m, nam, control)
|
||||
struct socket *so;
|
||||
int req;
|
||||
struct mbuf *m, *nam, *control;
|
||||
{
|
||||
register struct isopcb *isop = sotoisopcb(so);
|
||||
int s, error = 0;
|
||||
|
||||
if (req == PRU_CONTROL)
|
||||
return (iso_control(so, (int)m, (caddr_t)nam,
|
||||
(struct ifnet *)control));
|
||||
if ((isop == NULL && req != PRU_ATTACH) ||
|
||||
(control && control->m_len)) {
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
}
|
||||
switch (req) {
|
||||
|
||||
case PRU_ATTACH:
|
||||
if (isop != NULL) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
error = iso_pcballoc(so, &cltb);
|
||||
if (error)
|
||||
break;
|
||||
error = soreserve(so, cltp_sendspace, cltp_recvspace);
|
||||
if (error)
|
||||
break;
|
||||
break;
|
||||
|
||||
case PRU_DETACH:
|
||||
iso_pcbdetach(isop);
|
||||
break;
|
||||
|
||||
case PRU_BIND:
|
||||
error = iso_pcbbind(isop, nam);
|
||||
break;
|
||||
|
||||
case PRU_LISTEN:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
|
||||
case PRU_CONNECT:
|
||||
if (isop->isop_faddr) {
|
||||
error = EISCONN;
|
||||
break;
|
||||
}
|
||||
error = iso_pcbconnect(isop, nam);
|
||||
if (error == 0)
|
||||
soisconnected(so);
|
||||
break;
|
||||
|
||||
case PRU_CONNECT2:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
|
||||
case PRU_ACCEPT:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
|
||||
case PRU_DISCONNECT:
|
||||
if (isop->isop_faddr == 0) {
|
||||
error = ENOTCONN;
|
||||
break;
|
||||
}
|
||||
iso_pcbdisconnect(isop);
|
||||
so->so_state &= ~SS_ISCONNECTED; /* XXX */
|
||||
break;
|
||||
|
||||
case PRU_SHUTDOWN:
|
||||
socantsendmore(so);
|
||||
break;
|
||||
|
||||
case PRU_SEND:
|
||||
if (nam) {
|
||||
if (isop->isop_faddr) {
|
||||
error = EISCONN;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Must block input while temporarily connected.
|
||||
*/
|
||||
s = splnet();
|
||||
error = iso_pcbconnect(isop, nam);
|
||||
if (error) {
|
||||
splx(s);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (isop->isop_faddr == 0) {
|
||||
error = ENOTCONN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
error = cltp_output(isop, m);
|
||||
m = 0;
|
||||
if (nam) {
|
||||
iso_pcbdisconnect(isop);
|
||||
splx(s);
|
||||
}
|
||||
break;
|
||||
|
||||
case PRU_ABORT:
|
||||
soisdisconnected(so);
|
||||
iso_pcbdetach(isop);
|
||||
break;
|
||||
|
||||
case PRU_SOCKADDR:
|
||||
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:
|
||||
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:
|
||||
/*
|
||||
* stat: don't bother with a blocksize.
|
||||
*/
|
||||
return (0);
|
||||
|
||||
case PRU_SENDOOB:
|
||||
case PRU_FASTTIMO:
|
||||
case PRU_SLOWTIMO:
|
||||
case PRU_PROTORCV:
|
||||
case PRU_PROTOSEND:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
|
||||
case PRU_RCVD:
|
||||
case PRU_RCVOOB:
|
||||
return (EOPNOTSUPP); /* do not free mbuf's */
|
||||
|
||||
default:
|
||||
panic("cltp_usrreq");
|
||||
}
|
||||
release:
|
||||
if (control != NULL)
|
||||
m_freem(control);
|
||||
if (m != NULL)
|
||||
m_freem(m);
|
||||
return (error);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* @(#)cltp_var.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: cltp_var.h,v 1.2 1994/08/02 07:49:58 davidg 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 */
|
||||
#define CLTPOVAL_DST 0xc2 /* Destination TSAP -- required */
|
||||
#define CLTPOVAL_CSM 0xc3 /* Checksum parameter -- optional */
|
||||
|
||||
struct cltpstat {
|
||||
int cltps_hdrops;
|
||||
int cltps_badsum;
|
||||
int cltps_badlen;
|
||||
int cltps_noport;
|
||||
int cltps_ipackets;
|
||||
int cltps_opackets;
|
||||
};
|
||||
|
||||
#ifdef KERNEL
|
||||
struct isopcb cltb;
|
||||
struct cltpstat cltpstat;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,98 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)cons.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: cons.h,v 1.3 1994/08/21 06:14:15 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_CONS_H_
|
||||
#define _NETISO_CONS_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* $Header: /home/ncvs/src/sys/netiso/cons.h,v 1.3 1994/08/21 06:14:15 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/cons.h,v $
|
||||
*
|
||||
* interface between TP and CONS
|
||||
*/
|
||||
|
||||
#define CONSOPT_X25CRUD 0x01 /* set x.25 call request user data */
|
||||
|
||||
struct dte_addr {
|
||||
u_char dtea_addr[7];
|
||||
u_char dtea_niblen;
|
||||
};
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
#define CONN_OPEN 0x33
|
||||
#define CONN_CONFIRM 0x30
|
||||
#define CONN_REFUSE 0x31
|
||||
#define CONN_CLOSE 0x32
|
||||
|
||||
#define CONS_IS_DGM 0x1
|
||||
#define CONS_NOT_DGM 0x0
|
||||
|
||||
#ifndef PRC_NCMDS
|
||||
#include <sys/protosw.h>
|
||||
#endif /* PRC_NCMDS */
|
||||
|
||||
#define PRC_CONS_SEND_DONE 2 /* something unused in protosw.h */
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif
|
||||
@@ -1,199 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)cons_pcb.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: cons_pcb.h,v 1.3 1994/08/21 06:14:16 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_CONS_PCB_H_
|
||||
#define _NETISO_CONS_PCB_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/cons_pcb.h,v 1.3 1994/08/21 06:14:16 paul Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/cons_pcb.h,v $ */
|
||||
|
||||
/*
|
||||
* protocol control block for the connection oriented network service
|
||||
*/
|
||||
|
||||
/*
|
||||
* legit port #s for cons "transport" are 0..23 for su users only, and
|
||||
* 1024..1099 for public users
|
||||
*/
|
||||
#define X25_SBSIZE 512
|
||||
#define X25_PORT_RESERVED 24
|
||||
#define X25_PORT_USERMAX 1099
|
||||
#define X25_FACIL_LEN_MAX 109
|
||||
#define X25_PARTIAL_PKT_LEN_MAX (MLEN - sizeof(struct cons_pcb))
|
||||
|
||||
#ifndef ARGO_DEBUG
|
||||
#define X25_TTL 600 /* 5 min */
|
||||
#else /* ARGO_DEBUG */
|
||||
#define X25_TTL 120 /* 1 min */
|
||||
#endif /* ARGO_DEBUG */
|
||||
|
||||
struct cons_pcb {
|
||||
struct isopcb _co_isopcb;
|
||||
#define co_next _co_isopcb.isop_next
|
||||
/* prev used for netstat only */
|
||||
#define co_prev _co_isopcb.isop_prev
|
||||
#define co_head _co_isopcb.isop_head
|
||||
#define co_laddr _co_isopcb.isop_laddr
|
||||
#define co_faddr _co_isopcb.isop_faddr
|
||||
#define co_lport _co_isopcb.isop_laddr.siso_tsuffix
|
||||
#define co_fport _co_isopcb.isop_faddr.siso_tsuffix
|
||||
#define co_route _co_isopcb.isop_route
|
||||
#define co_socket _co_isopcb.isop_socket
|
||||
#define co_chanmask _co_isopcb.isop_chanmask
|
||||
#define co_negchanmask _co_isopcb.isop_negchanmask
|
||||
#define co_x25crud _co_isopcb.isop_x25crud
|
||||
#define co_x25crud_len _co_isopcb.isop_x25crud_len
|
||||
u_short co_state;
|
||||
u_char co_flags;
|
||||
u_short co_ttl; /* time to live timer */
|
||||
u_short co_init_ttl; /* initial value of ttl */
|
||||
int co_channel; /* logical channel */
|
||||
struct ifnet * co_ifp; /* interface */
|
||||
struct protosw *co_proto;
|
||||
|
||||
struct ifqueue co_pending; /* queue data to send when connection
|
||||
completes*/
|
||||
#define MAX_DTE_LEN 0x7 /* 17 bcd digits */
|
||||
struct dte_addr co_peer_dte;
|
||||
struct cons_pcb *co_myself; /* DEBUGGING AID */
|
||||
};
|
||||
|
||||
/*
|
||||
* X.25 Packet types
|
||||
*/
|
||||
#define XPKT_DATA 1
|
||||
#define XPKT_INTERRUPT 2
|
||||
#define XPKT_FLOWCONTROL 3 /* not delivered? */
|
||||
|
||||
/*
|
||||
* pcb xtates
|
||||
*/
|
||||
|
||||
#define CLOSED 0x0
|
||||
#define LISTENING 0x1
|
||||
#define CLOSING 0x2
|
||||
/* USABLE STATES MUST BE LAST */
|
||||
#define CONNECTING 0x3
|
||||
#define ACKWAIT 0x4
|
||||
#define OPEN 0x5
|
||||
#define MIN_USABLE_STATE CONNECTING
|
||||
|
||||
#define cons_NSTATES 0x6
|
||||
|
||||
|
||||
/* type */
|
||||
#define CONSF_OCRE 0x40 /* created on OUTPUT */
|
||||
#define CONSF_ICRE 0x20 /* created on INPUT */
|
||||
#define CONSF_unused 0x10 /* not used */
|
||||
#define CONSF_unused2 0x08 /* not used */
|
||||
#define CONSF_DGM 0x04 /* for dgm use only */
|
||||
#define CONSF_XTS 0x02 /* for cons-as-transport-service */
|
||||
#define CONSF_LOOPBACK 0x01 /* loopback was on when connection commenced */
|
||||
|
||||
#define X_NOCHANNEL 0x80
|
||||
|
||||
|
||||
struct cons_stat {
|
||||
u_int co_intr; /* input from eicon board */
|
||||
u_int co_restart; /* ecn_restart() request issued to board */
|
||||
u_int co_slowtimo; /* times slowtimo called */
|
||||
u_int co_timedout; /* connections closed by slowtimo */
|
||||
u_int co_ack; /* ECN_ACK indication came from eicon board */
|
||||
u_int co_receive; /* ECN_RECEIVE indication came from eicon board */
|
||||
u_int co_send; /* ECN_SEND request issued to board */
|
||||
u_int co_reset_in; /* ECN_RESET indication came from eicon board */
|
||||
u_int co_reset_out; /* ECN_RESET issued to the eicon board */
|
||||
u_int co_clear_in; /* ECN_CLEAR indication came from eicon board */
|
||||
u_int co_clear_out; /* ECN_CLEAR request issued to board */
|
||||
u_int co_refuse; /* ECN_REFUSE indication came from eicon board */
|
||||
u_int co_accept; /* ECN_ACCEPT indication came from eicon board */
|
||||
u_int co_connect; /* ECN_CONNECT indication came from eicon board */
|
||||
u_int co_call; /* ECN_CALL request issued to board */
|
||||
u_int co_Rdrops; /* bad pkt came from ll */
|
||||
u_int co_Xdrops; /* can't keep up */
|
||||
|
||||
u_int co_intrpt_pkts_in; /* interrupt packets in */
|
||||
u_int co_avg_qlen;
|
||||
u_int co_avg_qdrop;
|
||||
u_int co_active;
|
||||
|
||||
u_int co_noresources;
|
||||
u_int co_parse_facil_err;
|
||||
u_int co_addr_proto_consist_err;
|
||||
u_int co_no_copcb;
|
||||
} cons_stat;
|
||||
|
||||
u_char x25_error_stats[CONL_ERROR_MAX + 1];
|
||||
|
||||
struct ifqueue consintrq;
|
||||
|
||||
/* reasons for clear are in a data mbuf chained to a clear ecn_request */
|
||||
struct e_clear_data {
|
||||
u_char ecd_cause;
|
||||
u_char ecd_diagnostic;
|
||||
};
|
||||
|
||||
#ifdef KERNEL
|
||||
#define IncStat(XYZ) cons_stat.XYZ++
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif
|
||||
@@ -1,176 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)eonvar.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: eonvar.h,v 1.3 1994/08/21 06:14:17 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_EONVAR_H_
|
||||
#define _NETISO_EOBVAR_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
|
||||
#define EON_986_VERSION 0x3
|
||||
#define EON_VERSION 0x1
|
||||
|
||||
#define EON_CACHESIZE 30
|
||||
|
||||
#define E_FREE 1
|
||||
#define E_LINK 2
|
||||
#define E_ES 3
|
||||
#define E_IS 4
|
||||
|
||||
|
||||
/*
|
||||
* this overlays a sockaddr_iso
|
||||
*/
|
||||
|
||||
struct sockaddr_eon {
|
||||
u_char seon_len; /* Length */
|
||||
u_char seon_family; /* AF_ISO */
|
||||
u_char seon_status; /* overlays session suffixlen */
|
||||
#define EON_ESLINK_UP 0x1
|
||||
#define EON_ESLINK_DOWN 0x2
|
||||
#define EON_ISLINK_UP 0x10
|
||||
#define EON_ISLINK_DOWN 0x20
|
||||
/* no change is neither up or down */
|
||||
u_char seon_pad1; /* 0, overlays tsfxlen */
|
||||
u_char seon_adrlen;
|
||||
u_char seon_afi; /* 47 */
|
||||
u_char seon_idi[2]; /* 0006 */
|
||||
u_char seon_vers; /* 03 */
|
||||
u_char seon_glbnum[2]; /* see RFC 1069 */
|
||||
u_char seon_RDN[2]; /* see RFC 1070 */
|
||||
u_char seon_pad2[3]; /* see RFC 1070 */
|
||||
u_char seon_LAREA[2]; /* see RFC 1070 */
|
||||
u_char seon_pad3[2]; /* see RFC 1070 */
|
||||
/* right now ip addr is aligned -- be careful --
|
||||
* future revisions may have it u_char[4]
|
||||
*/
|
||||
u_int seon_ipaddr; /* a.b.c.d */
|
||||
u_char seon_protoid; /* NSEL */
|
||||
};
|
||||
|
||||
#ifdef EON_TEMPLATE
|
||||
struct sockaddr_eon eon_template = {
|
||||
sizeof (eon_template), AF_ISO, 0, 0, 0x14,
|
||||
0x47, 0x0, 0x6, 0x3, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#define DOWNBITS ( EON_ESLINK_DOWN | EON_ISLINK_DOWN )
|
||||
#define UPBITS ( EON_ESLINK_UP | EON_ISLINK_UP )
|
||||
|
||||
#define SIOCSEONCORE _IOWR('i',10, struct iso_ifreq) /* EON core member */
|
||||
#define SIOCGEONCORE _IOWR('i',11, struct iso_ifreq) /* EON core member */
|
||||
|
||||
struct eon_hdr {
|
||||
u_char eonh_vers; /* value 1 */
|
||||
u_char eonh_class; /* address multicast class, below */
|
||||
#define EON_NORMAL_ADDR 0x0
|
||||
#define EON_MULTICAST_ES 0x1
|
||||
#define EON_MULTICAST_IS 0x2
|
||||
#define EON_BROADCAST 0x3
|
||||
u_short eonh_csum; /* osi checksum (choke)*/
|
||||
};
|
||||
struct eon_iphdr {
|
||||
struct ip ei_ip;
|
||||
struct eon_hdr ei_eh;
|
||||
};
|
||||
#define EONIPLEN (sizeof(struct eon_hdr) + sizeof(struct ip))
|
||||
|
||||
/* stole these 2 fields of the flags for I-am-ES and I-am-IS */
|
||||
#define IFF_ES 0x400
|
||||
#define IFF_IS 0x800
|
||||
|
||||
struct eon_stat {
|
||||
int es_in_multi_es;
|
||||
int es_in_multi_is;
|
||||
int es_in_broad;
|
||||
int es_in_normal;
|
||||
int es_out_multi_es;
|
||||
int es_out_multi_is;
|
||||
int es_out_broad;
|
||||
int es_out_normal;
|
||||
int es_ipout;
|
||||
|
||||
int es_icmp[PRC_NCMDS];
|
||||
/* errors */
|
||||
int es_badcsum;
|
||||
int es_badhdr;
|
||||
} eonstat;
|
||||
|
||||
#undef IncStat
|
||||
#define IncStat(xxx) eonstat.xxx++
|
||||
|
||||
typedef struct qhdr {
|
||||
struct qhdr *link, *rlink;
|
||||
} *queue_t;
|
||||
|
||||
struct eon_llinfo {
|
||||
struct qhdr el_qhdr; /* keep all in a list */
|
||||
int el_flags; /* cache valid ? */
|
||||
int el_snpaoffset; /* IP address contained in dst nsap */
|
||||
struct rtentry *el_rt; /* back pointer to parent route */
|
||||
struct eon_iphdr el_ei; /* precomputed portion of hdr */
|
||||
struct route el_iproute; /* if direct route cache IP info */
|
||||
/* if gateway, cache secondary route */
|
||||
};
|
||||
#define el_iphdr el_ei.ei_ip
|
||||
#define el_eonhdr el_ei.ei_eh
|
||||
|
||||
#endif
|
||||
-1064
File diff suppressed because it is too large
Load Diff
@@ -1,141 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)esis.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: esis.h,v 1.3 1994/08/21 06:14:18 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_ESIS_H_
|
||||
#define _NETISO_ESIS_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* $Header: /home/ncvs/src/sys/netiso/esis.h,v 1.3 1994/08/21 06:14:18 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/esis.h,v $
|
||||
*/
|
||||
|
||||
#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 */
|
||||
|
||||
#define SNPAC_AGE 60 /* seconds */
|
||||
#define ESIS_CONFIG 60 /* seconds */
|
||||
#define ESIS_HT (ESIS_CONFIG * 2)
|
||||
|
||||
/*
|
||||
* Fixed part of an ESIS header
|
||||
*/
|
||||
struct esis_fixed {
|
||||
u_char esis_proto_id; /* network layer protocol identifier */
|
||||
u_char esis_hdr_len; /* length indicator (octets) */
|
||||
u_char esis_vers; /* version/protocol identifier extension */
|
||||
u_char esis_res1; /* reserved */
|
||||
u_char esis_type; /* type code */
|
||||
/* technically, type should be &='d 0x1f */
|
||||
#define ESIS_ESH 0x02 /* End System Hello */
|
||||
#define ESIS_ISH 0x04 /* Intermediate System Hello */
|
||||
#define ESIS_RD 0x06 /* Redirect */
|
||||
u_char esis_ht_msb; /* holding time (seconds) high byte */
|
||||
u_char esis_ht_lsb; /* holding time (seconds) low byte */
|
||||
u_char esis_cksum_msb; /* checksum high byte */
|
||||
u_char esis_cksum_lsb; /* checksum low byte */
|
||||
};
|
||||
/*
|
||||
* Values for ESIS datagram options
|
||||
*/
|
||||
#define ESISOVAL_NETMASK 0xe1 /* address mask option, RD PDU only */
|
||||
#define ESISOVAL_SNPAMASK 0xe2 /* snpa mask option, RD PDU only */
|
||||
#define ESISOVAL_ESCT 0xc6 /* end system conf. timer, ISH PDU only */
|
||||
|
||||
|
||||
#define ESIS_CKSUM_OFF 0x07
|
||||
#define ESIS_CKSUM_REQUIRED(pdu)\
|
||||
((pdu->esis_cksum_msb != 0) || (pdu->esis_cksum_lsb != 0))
|
||||
|
||||
#define ESIS_VERSION 1
|
||||
|
||||
struct esis_stat {
|
||||
u_short es_nomem; /* insufficient memory to send hello */
|
||||
u_short es_badcsum; /* incorrect checksum */
|
||||
u_short es_badvers; /* incorrect version number */
|
||||
u_short es_badtype; /* unknown pdu type field */
|
||||
u_short es_toosmall; /* packet too small */
|
||||
u_short es_eshsent; /* ESH sent */
|
||||
u_short es_eshrcvd; /* ESH rcvd */
|
||||
u_short es_ishsent; /* ISH sent */
|
||||
u_short es_ishrcvd; /* ISH rcvd */
|
||||
u_short es_rdsent; /* RD sent */
|
||||
u_short es_rdrcvd; /* RD rcvd */
|
||||
};
|
||||
|
||||
#ifdef KERNEL
|
||||
struct esis_stat esis_stat;
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* @(#)idrp_usrreq.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: idrp_usrreq.c,v 1.2 1994/08/02 07:50:16 davidg 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>
|
||||
|
||||
int 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
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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 0;
|
||||
}
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,961 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)if_cons.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: if_cons.c,v 1.3 1994/12/13 22:33:04 wollman Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* $Header: /home/ncvs/src/sys/netiso/if_cons.c,v 1.3 1994/12/13 22:33:04 wollman Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/if_cons.c,v $
|
||||
*
|
||||
* cons.c - Connection Oriented Network Service:
|
||||
* including support for a) user transport-level service,
|
||||
* b) COSNS below CLNP, and c) CONS below TP.
|
||||
*/
|
||||
|
||||
#ifdef TPCONS
|
||||
#ifdef KERNEL
|
||||
#ifdef ARGO_DEBUG
|
||||
#define Static
|
||||
unsigned LAST_CALL_PCB;
|
||||
#else /* ARGO_DEBUG */
|
||||
#define Static static
|
||||
#endif /* ARGO_DEBUG */
|
||||
|
||||
#ifndef SOCK_STREAM
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/tsleep.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/iso_errno.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_trace.h>
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/cons.h>
|
||||
#include <netiso/iso_pcb.h>
|
||||
|
||||
#include <netccitt/x25.h>
|
||||
#include <netccitt/pk.h>
|
||||
#include <netccitt/pk_var.h>
|
||||
#endif
|
||||
|
||||
#ifdef ARGO_DEBUG
|
||||
#define MT_XCONN 0x50
|
||||
#define MT_XCLOSE 0x51
|
||||
#define MT_XCONFIRM 0x52
|
||||
#define MT_XDATA 0x53
|
||||
#define MT_XHEADER 0x54
|
||||
#else
|
||||
#define MT_XCONN MT_DATA
|
||||
#define MT_XCLOSE MT_DATA
|
||||
#define MT_XCONFIRM MT_DATA
|
||||
#define MT_XDATA MT_DATA
|
||||
#define MT_XHEADER MT_HEADER
|
||||
#endif /* ARGO_DEBUG */
|
||||
|
||||
#define DONTCLEAR -1
|
||||
|
||||
/*********************************************************************
|
||||
* cons.c - CONS interface to the x.25 layer
|
||||
*
|
||||
* TODO: figure out what resources we might run out of besides mbufs.
|
||||
* If we run out of any of them (including mbufs) close and recycle
|
||||
* lru x% of the connections, for some parameter x.
|
||||
*
|
||||
* There are 2 interfaces from above:
|
||||
* 1) from TP0:
|
||||
* cons CO network service
|
||||
* TP associates a transport connection with a network connection.
|
||||
* cons_output( isop, m, len, isdgm==0 )
|
||||
* co_flags == 0
|
||||
* 2) from TP4:
|
||||
* It's a datagram service, like clnp is. - even though it calls
|
||||
* cons_output( isop, m, len, isdgm==1 )
|
||||
* it eventually goes through
|
||||
* cosns_output(ifp, m, dst).
|
||||
* TP4 permits multiplexing (reuse, possibly simultaneously) of the
|
||||
* network connections.
|
||||
* This means that many sockets (many tpcbs) may be associated with
|
||||
* this pklcd, hence cannot have a back ptr from pklcd to a tpcb.
|
||||
* co_flags & CONSF_DGM
|
||||
* co_socket is null since there may be many sockets that use this pklcd.
|
||||
*
|
||||
NOTE:
|
||||
streams would really be nice. sigh.
|
||||
NOTE:
|
||||
PVCs could be handled by config-ing a cons with an address and with the
|
||||
IFF_POINTTOPOINT flag on. This code would then have to skip the
|
||||
connection setup stuff for pt-to-pt links.
|
||||
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
#define CONS_IFQMAXLEN 5
|
||||
|
||||
|
||||
/* protosw pointers for getting to higher layer */
|
||||
Static struct protosw *CLNP_proto;
|
||||
Static struct protosw *TP_proto;
|
||||
Static struct protosw *X25_proto;
|
||||
Static int issue_clear_req();
|
||||
|
||||
#ifndef PHASEONE
|
||||
extern struct ifaddr *ifa_ifwithnet();
|
||||
#endif /* PHASEONE */
|
||||
|
||||
extern struct ifaddr *ifa_ifwithaddr();
|
||||
|
||||
extern struct isopcb tp_isopcb; /* chain of all TP pcbs */
|
||||
|
||||
|
||||
Static int parse_facil(), NSAPtoDTE(), make_partial_x25_packet();
|
||||
Static int FACILtoNSAP(), DTEtoNSAP();
|
||||
Static struct pklcd *cons_chan_to_pcb();
|
||||
|
||||
#define HIGH_NIBBLE 1
|
||||
#define LOW_NIBBLE 0
|
||||
|
||||
/*
|
||||
* NAME: nibble_copy()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* copies (len) nibbles from (src_octet), high or low nibble
|
||||
* to (dst_octet), high or low nibble,
|
||||
* src_nibble & dst_nibble should be:
|
||||
* HIGH_NIBBLE (1) if leftmost 4 bits/ most significant nibble
|
||||
* LOW_NIBBLE (0) if rightmost 4 bits/ least significant nibble
|
||||
* RETURNS: VOID
|
||||
*/
|
||||
void
|
||||
nibble_copy(src_octet, src_nibble, dst_octet, dst_nibble, len)
|
||||
register char *src_octet;
|
||||
register char *dst_octet;
|
||||
register unsigned src_nibble;
|
||||
register unsigned dst_nibble;
|
||||
int len;
|
||||
{
|
||||
|
||||
register i;
|
||||
register unsigned dshift, sshift;
|
||||
|
||||
IFDEBUG(D_CADDR)
|
||||
printf("nibble_copy ( 0x%x, 0x%x, 0x%x, 0x%x 0x%x)\n",
|
||||
src_octet, src_nibble, dst_octet, dst_nibble, len);
|
||||
ENDDEBUG
|
||||
#define SHIFT 0x4
|
||||
|
||||
dshift = dst_nibble << 2;
|
||||
sshift = src_nibble << 2;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
/* clear dst_nibble */
|
||||
*dst_octet &= ~(0xf<< dshift);
|
||||
|
||||
/* set dst nibble */
|
||||
*dst_octet |= ( 0xf & (*src_octet >> sshift))<< dshift;
|
||||
|
||||
dshift ^= SHIFT;
|
||||
sshift ^= SHIFT;
|
||||
src_nibble = 1-src_nibble;
|
||||
dst_nibble = 1-dst_nibble;
|
||||
src_octet += src_nibble;
|
||||
dst_octet += dst_nibble;
|
||||
}
|
||||
IFDEBUG(D_CADDR)
|
||||
printf("nibble_copy DONE\n");
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: nibble_match()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* compares src_octet/src_nibble and dst_octet/dst_nibble for len nibbles.
|
||||
* RETURNS: 0 if they differ, 1 if they are the same.
|
||||
*/
|
||||
int
|
||||
nibble_match( src_octet, src_nibble, dst_octet, dst_nibble, len)
|
||||
register char *src_octet;
|
||||
register char *dst_octet;
|
||||
register unsigned src_nibble;
|
||||
register unsigned dst_nibble;
|
||||
int len;
|
||||
{
|
||||
|
||||
register i;
|
||||
register unsigned dshift, sshift;
|
||||
u_char nibble_a, nibble_b;
|
||||
|
||||
IFDEBUG(D_CADDR)
|
||||
printf("nibble_match ( 0x%x, 0x%x, 0x%x, 0x%x 0x%x)\n",
|
||||
src_octet, src_nibble, dst_octet, dst_nibble, len);
|
||||
ENDDEBUG
|
||||
#define SHIFT 0x4
|
||||
|
||||
dshift = dst_nibble << 2;
|
||||
sshift = src_nibble << 2;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
nibble_b = ((*dst_octet)>>dshift) & 0xf;
|
||||
nibble_a = ( 0xf & (*src_octet >> sshift));
|
||||
if (nibble_b != nibble_a)
|
||||
return 0;
|
||||
|
||||
dshift ^= SHIFT;
|
||||
sshift ^= SHIFT;
|
||||
src_nibble = 1-src_nibble;
|
||||
dst_nibble = 1-dst_nibble;
|
||||
src_octet += src_nibble;
|
||||
dst_octet += dst_nibble;
|
||||
}
|
||||
IFDEBUG(D_CADDR)
|
||||
printf("nibble_match DONE\n");
|
||||
ENDDEBUG
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
**************************** NET PROTOCOL cons ***************************
|
||||
*/
|
||||
/*
|
||||
* NAME: cons_init()
|
||||
* CALLED FROM:
|
||||
* autoconf
|
||||
* FUNCTION:
|
||||
* initialize the protocol
|
||||
*/
|
||||
cons_init()
|
||||
{
|
||||
int tp_incoming(), clnp_incoming();
|
||||
|
||||
|
||||
CLNP_proto = pffindproto(AF_ISO, ISOPROTO_CLNP, SOCK_DGRAM);
|
||||
X25_proto = pffindproto(AF_ISO, ISOPROTO_X25, SOCK_STREAM);
|
||||
TP_proto = pffindproto(AF_ISO, ISOPROTO_TP0, SOCK_SEQPACKET);
|
||||
IFDEBUG(D_CCONS)
|
||||
printf("cons_init end : cnlp_proto 0x%x cons proto 0x%x tp proto 0x%x\n",
|
||||
CLNP_proto, X25_proto, TP_proto);
|
||||
ENDDEBUG
|
||||
#ifdef notdef
|
||||
pk_protolisten(0x81, 0, clnp_incoming);
|
||||
pk_protolisten(0x82, 0, esis_incoming);
|
||||
pk_protolisten(0x84, 0, tp8878_A_incoming);
|
||||
pk_protolisten(0, 0, tp_incoming);
|
||||
#endif
|
||||
}
|
||||
|
||||
tp_incoming(lcp, m)
|
||||
struct pklcd *lcp;
|
||||
register struct mbuf *m;
|
||||
{
|
||||
register struct isopcb *isop;
|
||||
int cons_tpinput();
|
||||
|
||||
if (iso_pcballoc((struct socket *)0, &tp_isopcb)) {
|
||||
pk_close(lcp);
|
||||
return;
|
||||
}
|
||||
isop = tp_isopcb.isop_next;
|
||||
lcp->lcd_upper = cons_tpinput;
|
||||
lcp->lcd_upnext = (caddr_t)isop;
|
||||
lcp->lcd_send(lcp); /* Confirms call */
|
||||
isop->isop_chan = (caddr_t)lcp;
|
||||
isop->isop_laddr = &isop->isop_sladdr;
|
||||
isop->isop_faddr = &isop->isop_sfaddr;
|
||||
DTEtoNSAP(isop->isop_laddr, &lcp->lcd_laddr);
|
||||
DTEtoNSAP(isop->isop_faddr, &lcp->lcd_faddr);
|
||||
parse_facil(lcp, isop, &(mtod(m, struct x25_packet *)->packet_data),
|
||||
m->m_pkthdr.len - PKHEADERLN);
|
||||
}
|
||||
|
||||
cons_tpinput(lcp, m0)
|
||||
struct mbuf *m0;
|
||||
struct pklcd *lcp;
|
||||
{
|
||||
register struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext;
|
||||
register struct x25_packet *xp;
|
||||
int cmd, ptype = CLEAR;
|
||||
|
||||
if (isop == 0)
|
||||
return;
|
||||
if (m0 == 0)
|
||||
goto dead;
|
||||
switch(m0->m_type) {
|
||||
case MT_DATA:
|
||||
case MT_OOBDATA:
|
||||
tpcons_input(m0, isop->isop_faddr, isop->isop_laddr, (caddr_t)lcp);
|
||||
return;
|
||||
|
||||
case MT_CONTROL:
|
||||
switch (ptype = pk_decode(mtod(m0, struct x25_packet *))) {
|
||||
|
||||
case RR:
|
||||
cmd = PRC_CONS_SEND_DONE;
|
||||
break;
|
||||
|
||||
case CALL_ACCEPTED:
|
||||
if (lcp->lcd_sb.sb_mb)
|
||||
lcp->lcd_send(lcp); /* XXX - fix this */
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
return;
|
||||
|
||||
dead:
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: cons_connect()
|
||||
* CALLED FROM:
|
||||
* tpcons_pcbconnect() when opening a new connection.
|
||||
* FUNCTION anD ARGUMENTS:
|
||||
* Figures out which device to use, finding a route if one doesn't
|
||||
* already exist.
|
||||
* RETURN VALUE:
|
||||
* returns E*
|
||||
*/
|
||||
cons_connect(isop)
|
||||
register struct isopcb *isop;
|
||||
{
|
||||
register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
|
||||
register struct mbuf *m;
|
||||
struct ifaddr *ifa;
|
||||
int error;
|
||||
|
||||
IFDEBUG(D_CCONN)
|
||||
printf("cons_connect(0x%x): ", isop);
|
||||
dump_isoaddr(isop->isop_faddr);
|
||||
printf("myaddr: ");
|
||||
dump_isoaddr(isop->isop_laddr);
|
||||
printf("\n" );
|
||||
ENDDEBUG
|
||||
NSAPtoDTE(isop->isop_faddr, &lcp->lcd_faddr);
|
||||
lcp->lcd_upper = cons_tpinput;
|
||||
lcp->lcd_upnext = (caddr_t)isop;
|
||||
IFDEBUG(D_CCONN)
|
||||
printf(
|
||||
"calling make_partial_x25_packet( 0x%x, 0x%x, 0x%x)\n",
|
||||
&lcp->lcd_faddr, &lcp->lcd_laddr,
|
||||
isop->isop_socket->so_proto->pr_protocol);
|
||||
ENDDEBUG
|
||||
if ((error = make_partial_x25_packet(isop, lcp, m)) == 0)
|
||||
error = pk_connect(lcp, &lcp->lcd_faddr);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
**************************** DEVICE cons ***************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* NAME: cons_ctlinput()
|
||||
* CALLED FROM:
|
||||
* lower layer when ECN_CLEAR occurs : this routine is here
|
||||
* for consistency - cons subnet service calls its higher layer
|
||||
* through the protosw entry.
|
||||
* FUNCTION & ARGUMENTS:
|
||||
* cmd is a PRC_* command, list found in ../sys/protosw.h
|
||||
* copcb is the obvious.
|
||||
* This serves the higher-layer cons service.
|
||||
* NOTE: this takes 3rd arg. because cons uses it to inform itself
|
||||
* of things (timeouts, etc) but has a pcb instead of an address.
|
||||
*/
|
||||
cons_ctlinput(cmd, sa, copcb)
|
||||
int cmd;
|
||||
struct sockaddr *sa;
|
||||
register struct pklcd *copcb;
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
find_error_reason( xp )
|
||||
register struct x25_packet *xp;
|
||||
{
|
||||
extern u_char x25_error_stats[];
|
||||
int error, cause;
|
||||
|
||||
if (xp) {
|
||||
cause = 4[(char *)xp];
|
||||
switch (cause) {
|
||||
case 0x00:
|
||||
case 0x80:
|
||||
/* DTE originated; look at the diagnostic */
|
||||
error = (CONL_ERROR_MASK | cause);
|
||||
goto done;
|
||||
|
||||
case 0x01: /* number busy */
|
||||
case 0x81:
|
||||
case 0x09: /* Out of order */
|
||||
case 0x89:
|
||||
case 0x11: /* Remot Procedure Error */
|
||||
case 0x91:
|
||||
case 0x19: /* reverse charging accept not subscribed */
|
||||
case 0x99:
|
||||
case 0x21: /* Incampat destination */
|
||||
case 0xa1:
|
||||
case 0x29: /* fast select accept not subscribed */
|
||||
case 0xa9:
|
||||
case 0x39: /* ship absent */
|
||||
case 0xb9:
|
||||
case 0x03: /* invalid facil request */
|
||||
case 0x83:
|
||||
case 0x0b: /* access barred */
|
||||
case 0x8b:
|
||||
case 0x13: /* local procedure error */
|
||||
case 0x93:
|
||||
case 0x05: /* network congestion */
|
||||
case 0x85:
|
||||
case 0x8d: /* not obtainable */
|
||||
case 0x0d:
|
||||
case 0x95: /* RPOA out of order */
|
||||
case 0x15:
|
||||
/* take out bit 8
|
||||
* so we don't have to have so many perror entries
|
||||
*/
|
||||
error = (CONL_ERROR_MASK | 0x100 | (cause & ~0x80));
|
||||
goto done;
|
||||
|
||||
case 0xc1: /* gateway-detected proc error */
|
||||
case 0xc3: /* gateway congestion */
|
||||
|
||||
error = (CONL_ERROR_MASK | 0x100 | cause);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
/* otherwise, a *hopefully* valid perror exists in the e_reason field */
|
||||
error = xp->packet_data;
|
||||
if (error = 0) {
|
||||
printf("Incoming PKT TYPE 0x%x with reason 0x%x\n",
|
||||
pk_decode(xp),
|
||||
cause);
|
||||
error = E_CO_HLI_DISCA;
|
||||
}
|
||||
|
||||
done:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
/*
|
||||
* NAME: make_partial_x25_packet()
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Makes part of an X.25 call packet, for use by x25.
|
||||
* (src) and (dst) are the NSAP-addresses of source and destination.
|
||||
* (buf) is a ptr to a buffer into which to write this partial header.
|
||||
*
|
||||
* 0 Facility length (in octets)
|
||||
* 1 Facility field, which is a set of:
|
||||
* m facil code
|
||||
* m+1 facil param len (for >2-byte facilities) in octets
|
||||
* m+2..p facil param field
|
||||
* q user data (protocol identification octet)
|
||||
*
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 if OK
|
||||
* E* if failed.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
* Stores facilites mbuf in X.25 control block, where the connect
|
||||
* routine knows where to look for it.
|
||||
*/
|
||||
|
||||
#ifdef X25_1984
|
||||
int cons_use_facils = 1;
|
||||
#else /* X25_1984 */
|
||||
int cons_use_facils = 0;
|
||||
#endif /* X25_1984 */
|
||||
|
||||
int cons_use_udata = 1; /* KLUDGE FOR DEBUGGING */
|
||||
|
||||
Static int
|
||||
make_partial_x25_packet(isop, lcp)
|
||||
struct isopcb *isop;
|
||||
struct pklcd *lcp;
|
||||
{
|
||||
u_int proto;
|
||||
int flag;
|
||||
caddr_t buf;
|
||||
register caddr_t ptr;
|
||||
register int len = 0;
|
||||
int buflen =0;
|
||||
caddr_t facil_len;
|
||||
int oddness = 0;
|
||||
struct mbuf *m;
|
||||
|
||||
|
||||
IFDEBUG(D_CCONN)
|
||||
printf("make_partial_x25_packet(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
|
||||
isop->isop_laddr, isop->isop_faddr, proto, m, flag);
|
||||
ENDDEBUG
|
||||
if (cons_use_udata) {
|
||||
if (isop->isop_x25crud_len > 0) {
|
||||
/*
|
||||
* The user specified something. Stick it in
|
||||
*/
|
||||
bcopy(isop->isop_x25crud, lcp->lcd_faddr.x25_udata,
|
||||
isop->isop_x25crud_len);
|
||||
lcp->lcd_faddr.x25_udlen = isop->isop_x25crud_len;
|
||||
}
|
||||
}
|
||||
|
||||
if (cons_use_facils == 0) {
|
||||
lcp->lcd_facilities = 0;
|
||||
return 0;
|
||||
}
|
||||
MGETHDR(m, MT_DATA, M_WAITOK);
|
||||
if (m == 0)
|
||||
return ENOBUFS;
|
||||
buf = mtod(m, caddr_t);
|
||||
ptr = buf;
|
||||
|
||||
/* ptr now points to facil length (len of whole facil field in OCTETS */
|
||||
facil_len = ptr ++;
|
||||
m->m_len = 0;
|
||||
pk_build_facilities(m, &lcp->lcd_faddr, 0);
|
||||
|
||||
IFDEBUG(D_CADDR)
|
||||
printf("make_partial calling: ptr 0x%x, len 0x%x\n", ptr,
|
||||
isop->isop_laddr->siso_addr.isoa_len);
|
||||
ENDDEBUG
|
||||
if (cons_use_facils) {
|
||||
*ptr++ = 0; /* Marker to separate X.25 facitilies from CCITT ones */
|
||||
*ptr++ = 0x0f;
|
||||
*ptr = 0xcb; /* calling facility code */
|
||||
ptr ++;
|
||||
ptr ++; /* leave room for facil param len (in OCTETS + 1) */
|
||||
ptr ++; /* leave room for the facil param len (in nibbles),
|
||||
* high two bits of which indicate full/partial NSAP
|
||||
*/
|
||||
len = isop->isop_laddr->siso_addr.isoa_len;
|
||||
bcopy( isop->isop_laddr->siso_data, ptr, len);
|
||||
*(ptr-2) = len+1; /* facil param len in octets */
|
||||
*(ptr-1) = len<<1; /* facil param len in nibbles */
|
||||
ptr += len;
|
||||
|
||||
IFDEBUG(D_CADDR)
|
||||
printf("make_partial called: ptr 0x%x, len 0x%x\n", ptr,
|
||||
isop->isop_faddr->siso_addr.isoa_len);
|
||||
ENDDEBUG
|
||||
*ptr = 0xc9; /* called facility code */
|
||||
ptr ++;
|
||||
ptr ++; /* leave room for facil param len (in OCTETS + 1) */
|
||||
ptr ++; /* leave room for the facil param len (in nibbles),
|
||||
* high two bits of which indicate full/partial NSAP
|
||||
*/
|
||||
len = isop->isop_faddr->siso_nlen;
|
||||
bcopy(isop->isop_faddr->siso_data, ptr, len);
|
||||
*(ptr-2) = len+1; /* facil param len = addr len + 1 for each of these
|
||||
* two length fields, in octets */
|
||||
*(ptr-1) = len<<1; /* facil param len in nibbles */
|
||||
ptr += len;
|
||||
|
||||
}
|
||||
*facil_len = ptr - facil_len - 1;
|
||||
if (*facil_len > MAX_FACILITIES)
|
||||
return E_CO_PNA_LONG;
|
||||
|
||||
buflen = (int)(ptr - buf);
|
||||
|
||||
IFDEBUG(D_CDUMP_REQ)
|
||||
register int i;
|
||||
|
||||
printf("ECN_CONNECT DATA buf 0x%x len %d (0x%x)\n",
|
||||
buf, buflen, buflen);
|
||||
for( i=0; i < buflen; ) {
|
||||
printf("+%d: %x %x %x %x %x %x %x %x\n",
|
||||
i,
|
||||
*(buf+i), *(buf+i+1), *(buf+i+2), *(buf+i+3),
|
||||
*(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7));
|
||||
i+=8;
|
||||
}
|
||||
ENDDEBUG
|
||||
IFDEBUG(D_CADDR)
|
||||
printf("make_partial returns buf 0x%x size 0x%x bytes\n",
|
||||
mtod(m, caddr_t), buflen);
|
||||
ENDDEBUG
|
||||
|
||||
if (buflen > MHLEN)
|
||||
return E_CO_PNA_LONG;
|
||||
|
||||
m->m_pkthdr.len = m->m_len = buflen;
|
||||
lcp->lcd_facilities = m;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: NSAPtoDTE()
|
||||
* CALLED FROM:
|
||||
* make_partial_x25_packet()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* get a DTE address from an NSAP-address (struct sockaddr_iso)
|
||||
* (dst_octet) is the octet into which to begin stashing the DTE addr
|
||||
* (dst_nibble) takes 0 or 1. 1 means begin filling in the DTE addr
|
||||
* in the high-order nibble of dst_octet. 0 means low-order nibble.
|
||||
* (addr) is the NSAP-address
|
||||
* (flag) is true if the transport suffix is to become the
|
||||
* last two digits of the DTE address
|
||||
* A DTE address is a series of ASCII digits
|
||||
*
|
||||
* A DTE address may have leading zeros. The are significant.
|
||||
* 1 digit per nibble, may be an odd number of nibbles.
|
||||
*
|
||||
* An NSAP-address has the DTE address in the IDI. Leading zeros are
|
||||
* significant. Trailing hex f indicates the end of the DTE address.
|
||||
* The IDI is a series of BCD digits, one per nibble.
|
||||
*
|
||||
* RETURNS
|
||||
* # significant digits in the DTE address, -1 if error.
|
||||
*/
|
||||
|
||||
Static int
|
||||
NSAPtoDTE(siso, sx25)
|
||||
register struct sockaddr_iso *siso;
|
||||
register struct sockaddr_x25 *sx25;
|
||||
{
|
||||
int dtelen = -1;
|
||||
|
||||
IFDEBUG(D_CADDR)
|
||||
printf("NSAPtoDTE: nsap: %s\n", clnp_iso_addrp(&siso->siso_addr));
|
||||
ENDDEBUG
|
||||
|
||||
if (siso->siso_data[0] == AFI_37) {
|
||||
register char *out = sx25->x25_addr;
|
||||
register char *in = siso->siso_data + 1;
|
||||
register int nibble;
|
||||
char *lim = siso->siso_data + siso->siso_nlen;
|
||||
char *olim = out+15;
|
||||
int lowNibble = 0;
|
||||
|
||||
while (in < lim) {
|
||||
nibble = ((lowNibble ? *in++ : (*in >> 4)) & 0xf) | 0x30;
|
||||
lowNibble ^= 1;
|
||||
if (nibble != 0x3f && out < olim)
|
||||
*out++ = nibble;
|
||||
}
|
||||
dtelen = out - sx25->x25_addr;
|
||||
*out++ = 0;
|
||||
} else {
|
||||
/* error = iso_8208snparesolve(addr, x121string, &x121strlen);*/
|
||||
register struct rtentry *rt;
|
||||
extern struct sockaddr_iso blank_siso;
|
||||
struct sockaddr_iso nsiso;
|
||||
|
||||
nsiso = blank_siso;
|
||||
bcopy(nsiso.siso_data, siso->siso_data,
|
||||
nsiso.siso_nlen = siso->siso_nlen);
|
||||
if (rt = rtalloc1(&nsiso, 1, 0UL)) {
|
||||
register struct sockaddr_x25 *sxx =
|
||||
(struct sockaddr_x25 *)rt->rt_gateway;
|
||||
register char *in = sxx->x25_addr;
|
||||
|
||||
rt->rt_use--;
|
||||
if (sxx && sxx->x25_family == AF_CCITT) {
|
||||
bcopy(sx25->x25_addr, sxx->x25_addr, sizeof(sx25->x25_addr));
|
||||
while (*in++) {}
|
||||
dtelen = in - sxx->x25_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dtelen;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: FACILtoNSAP()
|
||||
* CALLED FROM:
|
||||
* parse_facil()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Creates and NSAP in the sockaddr_iso (addr) from the
|
||||
* x.25 facility found at buf - 1.
|
||||
* RETURNS:
|
||||
* 0 if ok, -1 if error.
|
||||
*/
|
||||
|
||||
Static int
|
||||
FACILtoNSAP(addr, buf)
|
||||
register u_char *buf;
|
||||
register struct sockaddr_iso *addr;
|
||||
{
|
||||
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",
|
||||
buf, buf_len, addr );
|
||||
ENDDEBUG
|
||||
|
||||
len_in_nibbles = *buf & 0x3f;
|
||||
/* despite the fact that X.25 makes us put a length in nibbles
|
||||
* here, the NSAP-addrs are always in full octets
|
||||
*/
|
||||
switch (*buf++ & 0xc0) {
|
||||
case 0:
|
||||
/* Entire OSI NSAP address */
|
||||
bcopy((caddr_t)buf, addr->siso_data, addr->siso_nlen = buf_len);
|
||||
break;
|
||||
|
||||
case 40:
|
||||
/* Partial OSI NSAP address, assume trailing */
|
||||
if (buf_len + addr->siso_nlen > sizeof(addr->siso_addr))
|
||||
return -1;
|
||||
bcopy((caddr_t)buf, TSEL(addr), buf_len);
|
||||
addr->siso_nlen += buf_len;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Rather than blow away the connection, just ignore and use
|
||||
NSAP from DTE */;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Static
|
||||
init_siso(siso)
|
||||
register struct sockaddr_iso *siso;
|
||||
{
|
||||
siso->siso_len = sizeof (*siso);
|
||||
siso->siso_family = AF_ISO;
|
||||
siso->siso_data[0] = AFI_37;
|
||||
siso->siso_nlen = 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: DTEtoNSAP()
|
||||
* CALLED FROM:
|
||||
* parse_facil()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Creates a type 37 NSAP in the sockaddr_iso (addr)
|
||||
* from a DTE address found in a sockaddr_x25.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 if ok; E* otherwise.
|
||||
*/
|
||||
|
||||
Static int
|
||||
DTEtoNSAP(addr, sx)
|
||||
struct sockaddr_iso *addr;
|
||||
struct sockaddr_x25 *sx;
|
||||
{
|
||||
register char *in, *out;
|
||||
register int first;
|
||||
int pad_tail = 0;
|
||||
int src_len;
|
||||
|
||||
|
||||
init_siso(addr);
|
||||
in = sx->x25_addr;
|
||||
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 |= 0xf & *in++;
|
||||
if (src_len & 1) {
|
||||
*out++ = first;
|
||||
first = 0;
|
||||
}
|
||||
else first <<= 4;
|
||||
}
|
||||
if (pad_tail)
|
||||
out[-1] |= 0xf;
|
||||
return 0; /* ok */
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* parses (buf_len) bytes beginning at (buf) and finds
|
||||
* a called nsap, a calling nsap, and protocol identifier.
|
||||
* RETURNS:
|
||||
* 0 if ok, E* otherwise.
|
||||
*/
|
||||
|
||||
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 int i;
|
||||
register u_char *ptr = (u_char *)buf;
|
||||
u_char *ptr_lim, *facil_lim;
|
||||
int facil_param_len, facil_len;
|
||||
|
||||
IFDEBUG(D_CADDR)
|
||||
printf("parse_facil(0x%x, 0x%x, 0x%x, 0x%x)\n",
|
||||
lcp, isop, buf, buf_len);
|
||||
dump_buf(buf, buf_len);
|
||||
ENDDEBUG
|
||||
|
||||
/* find the beginnings of the facility fields in buf
|
||||
* by skipping over the called & calling DTE addresses
|
||||
* i <- # nibbles in called + # nibbles in calling
|
||||
* i += 1 so that an odd nibble gets rounded up to even
|
||||
* before dividing by 2, then divide by two to get # octets
|
||||
*/
|
||||
i = (int)(*ptr >> 4) + (int)(*ptr&0xf);
|
||||
i++;
|
||||
ptr += i >> 1;
|
||||
ptr ++; /* plus one for the DTE lengths byte */
|
||||
|
||||
/* ptr now is at facil_length field */
|
||||
facil_len = *ptr++;
|
||||
facil_lim = ptr + facil_len;
|
||||
IFDEBUG(D_CADDR)
|
||||
printf("parse_facils: facil length is 0x%x\n", (int) facil_len);
|
||||
ENDDEBUG
|
||||
|
||||
while (ptr < facil_lim) {
|
||||
/* get NSAP addresses from facilities */
|
||||
switch (*ptr++) {
|
||||
case 0xcb:
|
||||
/* calling NSAP */
|
||||
facil_param_len = FACILtoNSAP(isop->isop_faddr, ptr);
|
||||
break;
|
||||
case 0xc9:
|
||||
/* called NSAP */
|
||||
facil_param_len = FACILtoNSAP(isop->isop_laddr, ptr);
|
||||
break;
|
||||
|
||||
/* from here to default are legit cases that I ignore */
|
||||
/* variable length */
|
||||
case 0xca: /* end-to-end transit delay negot */
|
||||
case 0xc6: /* network user id */
|
||||
case 0xc5: /* charging info : indicating monetary unit */
|
||||
case 0xc2: /* charging info : indicating segment count */
|
||||
case 0xc1: /* charging info : indicating call duration */
|
||||
case 0xc4: /* RPOA extended format */
|
||||
case 0xc3: /* call redirection notification */
|
||||
facil_param_len = 0;
|
||||
break;
|
||||
|
||||
/* 1 octet */
|
||||
case 0x0a: /* min. throughput class negot */
|
||||
case 0x02: /* throughput class */
|
||||
case 0x03: case 0x47: /* CUG shit */
|
||||
case 0x0b: /* expedited data negot */
|
||||
case 0x01: /* Fast select or reverse charging
|
||||
(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;
|
||||
|
||||
/* any 2 octets */
|
||||
case 0x42: /* pkt size */
|
||||
case 0x43: /* win size */
|
||||
case 0x44: /* RPOA basic format */
|
||||
case 0x41: /* bilateral CUG shit */
|
||||
case 0x49: /* transit delay selection and indication */
|
||||
facil_param_len = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf(
|
||||
"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 */
|
||||
ptr += facil_param_len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TPCONS */
|
||||
@@ -1,608 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)if_eon.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: if_eon.c,v 1.4 1995/05/30 08:10:45 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* $Header: /home/ncvs/src/sys/netiso/if_eon.c,v 1.4 1995/05/30 08:10:45 rgrimes Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/if_eon.c,v $
|
||||
*
|
||||
* EON rfc
|
||||
* Layer between IP and CLNL
|
||||
*
|
||||
* TODO:
|
||||
* Put together a current rfc986 address format and get the right offset
|
||||
* for the nsel
|
||||
*/
|
||||
|
||||
#ifdef EON
|
||||
#define NEON 1
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/route.h>
|
||||
#include <machine/mtpr.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/iso_snpac.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/iso_errno.h>
|
||||
#include <netiso/eonvar.h>
|
||||
|
||||
extern struct timeval time;
|
||||
|
||||
#define EOK 0
|
||||
|
||||
int eoninput();
|
||||
int eonoutput();
|
||||
int eonioctl();
|
||||
int eonattach();
|
||||
int eoninit();
|
||||
void eonrtrequest();
|
||||
struct ifnet eonif[1];
|
||||
|
||||
eonprotoinit() {
|
||||
(void) eonattach();
|
||||
}
|
||||
|
||||
struct eon_llinfo eon_llinfo;
|
||||
#define PROBE_OK 0;
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: eonattach
|
||||
*
|
||||
* PURPOSE: autoconf attach routine
|
||||
*
|
||||
* RETURNS: void
|
||||
*/
|
||||
|
||||
eonattach()
|
||||
{
|
||||
register struct ifnet *ifp = eonif;
|
||||
|
||||
IFDEBUG(D_EON)
|
||||
printf("eonattach()\n");
|
||||
ENDDEBUG
|
||||
ifp->if_unit = 0;
|
||||
ifp->if_name = "eon";
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
/* since everything will go out over ether or token ring */
|
||||
|
||||
ifp->if_ioctl = eonioctl;
|
||||
ifp->if_output = eonoutput;
|
||||
ifp->if_type = IFT_EON;
|
||||
ifp->if_addrlen = 5;
|
||||
ifp->if_hdrlen = EONIPLEN;
|
||||
ifp->if_flags = IFF_BROADCAST;
|
||||
if_attach(ifp);
|
||||
eonioctl(ifp, SIOCSIFADDR, (caddr_t)ifp->if_addrlist);
|
||||
eon_llinfo.el_qhdr.link =
|
||||
eon_llinfo.el_qhdr.rlink = &(eon_llinfo.el_qhdr);
|
||||
|
||||
IFDEBUG(D_EON)
|
||||
printf("eonattach()\n");
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: eonioctl
|
||||
*
|
||||
* PURPOSE: io controls - ifconfig
|
||||
* need commands to
|
||||
* link-UP (core addr) (flags: ES, IS)
|
||||
* link-DOWN (core addr) (flags: ES, IS)
|
||||
* must be callable from kernel or user
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*/
|
||||
eonioctl(ifp, cmd, data)
|
||||
register struct ifnet *ifp;
|
||||
int cmd;
|
||||
register caddr_t data;
|
||||
{
|
||||
int s = splimp();
|
||||
register int error = 0;
|
||||
|
||||
IFDEBUG(D_EON)
|
||||
printf("eonioctl (cmd 0x%x) \n", cmd);
|
||||
ENDDEBUG
|
||||
|
||||
switch (cmd) {
|
||||
register struct ifaddr *ifa;
|
||||
|
||||
case SIOCSIFADDR:
|
||||
if (ifa = (struct ifaddr *)data) {
|
||||
ifp->if_flags |= IFF_UP;
|
||||
if (ifa->ifa_addr->sa_family != AF_LINK)
|
||||
ifa->ifa_rtrequest = eonrtrequest;
|
||||
}
|
||||
break;
|
||||
}
|
||||
splx(s);
|
||||
return(error);
|
||||
}
|
||||
|
||||
|
||||
eoniphdr(hdr, loc, ro, class, zero)
|
||||
struct route *ro;
|
||||
register struct eon_iphdr *hdr;
|
||||
caddr_t loc;
|
||||
{
|
||||
struct mbuf mhead;
|
||||
register struct sockaddr_in *sin = (struct sockaddr_in *)&ro->ro_dst;
|
||||
if (zero) {
|
||||
bzero((caddr_t)hdr, sizeof (*hdr));
|
||||
bzero((caddr_t)ro, sizeof (*ro));
|
||||
}
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof (*sin);
|
||||
bcopy(loc, (caddr_t)&sin->sin_addr, sizeof(struct in_addr));
|
||||
/*
|
||||
* If there is a cached route,
|
||||
* check that it is to the same destination
|
||||
* and is still up. If not, free it and try again.
|
||||
*/
|
||||
if (ro->ro_rt) {
|
||||
struct sockaddr_in *dst =
|
||||
(struct sockaddr_in *)rt_key(ro->ro_rt);
|
||||
if ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
|
||||
sin->sin_addr.s_addr != dst->sin_addr.s_addr) {
|
||||
RTFREE(ro->ro_rt);
|
||||
ro->ro_rt = (struct rtentry *)0;
|
||||
}
|
||||
}
|
||||
rtalloc(ro);
|
||||
if (ro->ro_rt)
|
||||
ro->ro_rt->rt_use++;
|
||||
hdr->ei_ip.ip_dst = sin->sin_addr;
|
||||
hdr->ei_ip.ip_p = IPPROTO_EON;
|
||||
hdr->ei_ip.ip_ttl = MAXTTL;
|
||||
hdr->ei_eh.eonh_class = class;
|
||||
hdr->ei_eh.eonh_vers = EON_VERSION;
|
||||
hdr->ei_eh.eonh_csum = 0;
|
||||
mhead.m_data = (caddr_t) &hdr->ei_eh;
|
||||
mhead.m_len = sizeof(struct eon_hdr);
|
||||
mhead.m_next = 0;
|
||||
IFDEBUG(D_EON)
|
||||
printf("eonoutput : gen csum (0x%x, offset %d, datalen %d)\n",
|
||||
&mhead,
|
||||
_offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr));
|
||||
ENDDEBUG
|
||||
iso_gen_csum(&mhead,
|
||||
_offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr));
|
||||
}
|
||||
/*
|
||||
* FUNCTION: eonrtrequest
|
||||
*
|
||||
* PURPOSE: maintains list of direct eon recipients.
|
||||
* sets up IP route for rest.
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*/
|
||||
void
|
||||
eonrtrequest(cmd, rt, gate)
|
||||
register struct rtentry *rt;
|
||||
register struct sockaddr *gate;
|
||||
{
|
||||
unsigned long zerodst = 0;
|
||||
caddr_t ipaddrloc = (caddr_t) &zerodst;
|
||||
register struct eon_llinfo *el = (struct eon_llinfo *)rt->rt_llinfo;
|
||||
|
||||
/*
|
||||
* Common Housekeeping
|
||||
*/
|
||||
switch (cmd) {
|
||||
case RTM_DELETE:
|
||||
if (el) {
|
||||
remque(&(el->el_qhdr));
|
||||
if (el->el_iproute.ro_rt)
|
||||
RTFREE(el->el_iproute.ro_rt);
|
||||
Free(el);
|
||||
rt->rt_llinfo = 0;
|
||||
}
|
||||
return;
|
||||
|
||||
case RTM_ADD:
|
||||
case RTM_RESOLVE:
|
||||
rt->rt_rmx.rmx_mtu = loif->if_mtu; /* unless better below */
|
||||
R_Malloc(el, struct eon_llinfo *, sizeof(*el));
|
||||
rt->rt_llinfo = (caddr_t)el;
|
||||
if (el == 0)
|
||||
return;
|
||||
Bzero(el, sizeof(*el));
|
||||
insque(&(el->el_qhdr), &eon_llinfo.el_qhdr);
|
||||
el->el_rt = rt;
|
||||
break;
|
||||
}
|
||||
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)
|
||||
el->el_snpaoffset = *(u_char *)LLADDR(SDL(gate));
|
||||
else
|
||||
ipaddrloc = LLADDR(SDL(gate));
|
||||
break;
|
||||
case AF_INET:
|
||||
#define SIN(x) ((struct sockaddr_in *)x)
|
||||
ipaddrloc = (caddr_t) &SIN(gate)->sin_addr;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
el->el_flags |= RTF_UP;
|
||||
eoniphdr(&el->el_ei, ipaddrloc, &el->el_iproute, EON_NORMAL_ADDR, 0);
|
||||
if (el->el_iproute.ro_rt)
|
||||
rt->rt_rmx.rmx_mtu = el->el_iproute.ro_rt->rt_rmx.rmx_mtu
|
||||
- sizeof(el->el_ei);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: eoninit
|
||||
*
|
||||
* PURPOSE: initialization
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*/
|
||||
|
||||
eoninit(unit)
|
||||
int unit;
|
||||
{
|
||||
printf("eon driver-init eon%d\n", unit);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: eonoutput
|
||||
*
|
||||
* PURPOSE: prepend an eon header and hand to IP
|
||||
* ARGUMENTS: (ifp) is points to the ifnet structure for this unit/device
|
||||
* (m) is an mbuf *, *m is a CLNL packet
|
||||
* (dst) is a destination address - have to interp. as
|
||||
* multicast or broadcast or real address.
|
||||
*
|
||||
* RETURNS: unix error code
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
*/
|
||||
eonoutput(ifp, m, dst, rt)
|
||||
struct ifnet *ifp;
|
||||
register struct mbuf *m; /* packet */
|
||||
struct sockaddr_iso *dst; /* destination addr */
|
||||
struct rtentry *rt;
|
||||
{
|
||||
register struct eon_llinfo *el;
|
||||
register struct eon_iphdr *ei;
|
||||
struct route *ro;
|
||||
int datalen;
|
||||
struct mbuf *mh;
|
||||
int error = 0, class = 0, alen = 0;
|
||||
caddr_t ipaddrloc;
|
||||
static struct eon_iphdr eon_iphdr;
|
||||
static struct route route;
|
||||
|
||||
IFDEBUG(D_EON)
|
||||
printf("eonoutput \n" );
|
||||
ENDDEBUG
|
||||
|
||||
ifp->if_lastchange = time;
|
||||
ifp->if_opackets++;
|
||||
if (rt == 0 || (el = (struct eon_llinfo *)rt->rt_llinfo) == 0) {
|
||||
if (dst->siso_family == AF_LINK) {
|
||||
register struct sockaddr_dl *sdl = (struct sockaddr_dl *)dst;
|
||||
|
||||
ipaddrloc = LLADDR(sdl);
|
||||
alen = sdl->sdl_alen;
|
||||
} else if (dst->siso_family == AF_ISO && dst->siso_data[0] == AFI_SNA) {
|
||||
alen = dst->siso_nlen - 1;
|
||||
ipaddrloc = (caddr_t) dst->siso_data + 1;
|
||||
}
|
||||
switch (alen) {
|
||||
case 5:
|
||||
class = 4[(u_char *)ipaddrloc];
|
||||
case 4:
|
||||
ro = &route;
|
||||
ei = &eon_iphdr;
|
||||
eoniphdr(ei, ipaddrloc, ro, class, 1);
|
||||
goto send;
|
||||
}
|
||||
einval:
|
||||
error = EINVAL;
|
||||
goto flush;
|
||||
}
|
||||
if ((el->el_flags & RTF_UP) == 0) {
|
||||
eonrtrequest(RTM_CHANGE, rt, (struct sockaddr *)0);
|
||||
if ((el->el_flags & RTF_UP) == 0) {
|
||||
error = EHOSTUNREACH;
|
||||
goto flush;
|
||||
}
|
||||
}
|
||||
if ((m->m_flags & M_PKTHDR) == 0) {
|
||||
printf("eon: got non headered packet\n");
|
||||
goto einval;
|
||||
}
|
||||
ei = &el->el_ei;
|
||||
ro = &el->el_iproute;
|
||||
if (el->el_snpaoffset) {
|
||||
if (dst->siso_family == AF_ISO) {
|
||||
bcopy((caddr_t) &dst->siso_data[el->el_snpaoffset],
|
||||
(caddr_t) &ei->ei_ip.ip_dst, sizeof(ei->ei_ip.ip_dst));
|
||||
} else
|
||||
goto einval;
|
||||
}
|
||||
send:
|
||||
/* put an eon_hdr in the buffer, prepended by an ip header */
|
||||
datalen = m->m_pkthdr.len + EONIPLEN;
|
||||
MGETHDR(mh, M_DONTWAIT, MT_HEADER);
|
||||
if(mh == (struct mbuf *)0)
|
||||
goto flush;
|
||||
mh->m_next = m;
|
||||
m = mh;
|
||||
MH_ALIGN(m, sizeof(struct eon_iphdr));
|
||||
m->m_len = sizeof(struct eon_iphdr);
|
||||
ifp->if_obytes +=
|
||||
(ei->ei_ip.ip_len = (u_short)(m->m_pkthdr.len = datalen));
|
||||
*mtod(m, struct eon_iphdr *) = *ei;
|
||||
|
||||
IFDEBUG(D_EON)
|
||||
printf("eonoutput dst ip addr : %x\n", ei->ei_ip.ip_dst.s_addr);
|
||||
printf("eonoutput ip_output : eonip header:\n");
|
||||
dump_buf(ei, sizeof(struct eon_iphdr));
|
||||
ENDDEBUG
|
||||
|
||||
error = ip_output(m, (struct mbuf *)0, ro, 0, NULL);
|
||||
m = 0;
|
||||
if (error) {
|
||||
ifp->if_oerrors++;
|
||||
ifp->if_opackets--;
|
||||
ifp->if_obytes -= datalen;
|
||||
}
|
||||
flush:
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return error;
|
||||
}
|
||||
|
||||
eoninput(m, iphlen)
|
||||
register struct mbuf *m;
|
||||
int iphlen;
|
||||
{
|
||||
register struct eon_hdr *eonhdr;
|
||||
register struct ip *iphdr;
|
||||
struct ifnet *eonifp;
|
||||
int s;
|
||||
|
||||
eonifp = &eonif[0]; /* kludge - really want to give CLNP
|
||||
* the ifp for eon, not for the real device
|
||||
*/
|
||||
|
||||
IFDEBUG(D_EON)
|
||||
printf("eoninput() 0x%x m_data 0x%x m_len 0x%x dequeued\n",
|
||||
m, m?m->m_data:0, m?m->m_len:0);
|
||||
ENDDEBUG
|
||||
|
||||
if (m == 0)
|
||||
return;
|
||||
if (iphlen > sizeof (struct ip))
|
||||
ip_stripoptions(m, (struct mbuf *)0);
|
||||
if (m->m_len < EONIPLEN) {
|
||||
if ((m = m_pullup(m, EONIPLEN)) == 0) {
|
||||
IncStat(es_badhdr);
|
||||
drop:
|
||||
IFDEBUG(D_EON)
|
||||
printf("eoninput: DROP \n" );
|
||||
ENDDEBUG
|
||||
eonifp->if_ierrors ++;
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
eonif->if_ibytes += m->m_pkthdr.len;
|
||||
eonif->if_lastchange = time;
|
||||
iphdr = mtod(m, struct ip *);
|
||||
/* do a few checks for debugging */
|
||||
if( iphdr->ip_p != IPPROTO_EON ) {
|
||||
IncStat(es_badhdr);
|
||||
goto drop;
|
||||
}
|
||||
/* temporarily drop ip header from the mbuf */
|
||||
m->m_data += sizeof(struct ip);
|
||||
eonhdr = mtod(m, struct eon_hdr *);
|
||||
if( iso_check_csum( m, sizeof(struct eon_hdr) ) != EOK ) {
|
||||
IncStat(es_badcsum);
|
||||
goto drop;
|
||||
}
|
||||
m->m_data -= sizeof(struct ip);
|
||||
|
||||
IFDEBUG(D_EON)
|
||||
printf("eoninput csum ok class 0x%x\n", eonhdr->eonh_class );
|
||||
printf("eoninput: eon header:\n");
|
||||
dump_buf(eonhdr, sizeof(struct eon_hdr));
|
||||
ENDDEBUG
|
||||
|
||||
/* checks for debugging */
|
||||
if( eonhdr->eonh_vers != EON_VERSION) {
|
||||
IncStat(es_badhdr);
|
||||
goto drop;
|
||||
}
|
||||
m->m_flags &= ~(M_BCAST|M_MCAST);
|
||||
switch( eonhdr->eonh_class) {
|
||||
case EON_BROADCAST:
|
||||
IncStat(es_in_broad);
|
||||
m->m_flags |= M_BCAST;
|
||||
break;
|
||||
case EON_NORMAL_ADDR:
|
||||
IncStat(es_in_normal);
|
||||
break;
|
||||
case EON_MULTICAST_ES:
|
||||
IncStat(es_in_multi_es);
|
||||
m->m_flags |= M_MCAST;
|
||||
break;
|
||||
case EON_MULTICAST_IS:
|
||||
IncStat(es_in_multi_is);
|
||||
m->m_flags |= M_MCAST;
|
||||
break;
|
||||
}
|
||||
eonifp->if_ipackets++;
|
||||
|
||||
{
|
||||
/* put it on the CLNP queue and set soft interrupt */
|
||||
struct ifqueue *ifq;
|
||||
extern struct ifqueue clnlintrq;
|
||||
|
||||
m->m_pkthdr.rcvif = eonifp; /* KLUDGE */
|
||||
IFDEBUG(D_EON)
|
||||
printf("eoninput to clnl IFQ\n");
|
||||
ENDDEBUG
|
||||
ifq = &clnlintrq;
|
||||
s = splimp();
|
||||
if (IF_QFULL(ifq)) {
|
||||
IF_DROP(ifq);
|
||||
m_freem(m);
|
||||
eonifp->if_iqdrops++;
|
||||
eonifp->if_ipackets--;
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
IF_ENQUEUE(ifq, m);
|
||||
IFDEBUG(D_EON)
|
||||
printf(
|
||||
"0x%x enqueued on clnp Q: m_len 0x%x m_type 0x%x m_data 0x%x\n",
|
||||
m, m->m_len, m->m_type, m->m_data);
|
||||
dump_buf(mtod(m, caddr_t), m->m_len);
|
||||
ENDDEBUG
|
||||
schednetisr(NETISR_ISO);
|
||||
splx(s);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
eonctlinput(cmd, sin)
|
||||
int cmd;
|
||||
struct sockaddr_in *sin;
|
||||
{
|
||||
extern u_char inetctlerrmap[];
|
||||
|
||||
IFDEBUG(D_EON)
|
||||
printf("eonctlinput: cmd 0x%x addr: ", cmd);
|
||||
dump_isoaddr(sin);
|
||||
printf("\n");
|
||||
ENDDEBUG
|
||||
|
||||
if (cmd < 0 || cmd > PRC_NCMDS)
|
||||
return 0;
|
||||
|
||||
IncStat(es_icmp[cmd]);
|
||||
switch (cmd) {
|
||||
|
||||
case PRC_QUENCH:
|
||||
case PRC_QUENCH2:
|
||||
/* TODO: set the dec bit */
|
||||
break;
|
||||
case PRC_TIMXCEED_REASS:
|
||||
case PRC_ROUTEDEAD:
|
||||
case PRC_HOSTUNREACH:
|
||||
case PRC_UNREACH_NET:
|
||||
case PRC_IFDOWN:
|
||||
case PRC_UNREACH_HOST:
|
||||
case PRC_HOSTDEAD:
|
||||
case PRC_TIMXCEED_INTRANS:
|
||||
/* TODO: mark the link down */
|
||||
break;
|
||||
|
||||
case PRC_UNREACH_PROTOCOL:
|
||||
case PRC_UNREACH_PORT:
|
||||
case PRC_UNREACH_SRCFAIL:
|
||||
case PRC_REDIRECT_NET:
|
||||
case PRC_REDIRECT_HOST:
|
||||
case PRC_REDIRECT_TOSNET:
|
||||
case PRC_REDIRECT_TOSHOST:
|
||||
case PRC_MSGSIZE:
|
||||
case PRC_PARAMPROB:
|
||||
/* printf("eonctlinput: ICMP cmd 0x%x\n", cmd );*/
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,919 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)iso.c 8.2 (Berkeley) 11/15/93
|
||||
* $Id: iso.c,v 1.3 1995/04/26 18:10:58 pst Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* $Header: /home/ncvs/src/sys/netiso/iso.c,v 1.3 1995/04/26 18:10:58 pst Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/iso.c,v $
|
||||
*
|
||||
* iso.c: miscellaneous routines to support the iso address family
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/iso_snpac.h>
|
||||
#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 */
|
||||
int ether_output();
|
||||
void llc_rtrequest();
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_addrmatch1
|
||||
*
|
||||
* PURPOSE: decide if the two iso_addrs passed are equal
|
||||
*
|
||||
* RETURNS: true if the addrs match, false if they do not
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
iso_addrmatch1(isoaa, isoab)
|
||||
register struct iso_addr *isoaa, *isoab; /* addresses to check */
|
||||
{
|
||||
u_int compare_len;
|
||||
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len,
|
||||
isoab->isoa_len);
|
||||
printf("a:\n");
|
||||
dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len);
|
||||
printf("b:\n");
|
||||
dump_buf(isoab->isoa_genaddr, isoab->isoa_len);
|
||||
ENDDEBUG
|
||||
|
||||
if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) {
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf("iso_addrmatch1: returning false because of lengths\n");
|
||||
ENDDEBUG
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/* TODO : generalize this to all afis with masks */
|
||||
if( isoaa->isoa_afi == AFI_37 ) {
|
||||
/* must not compare 2 least significant digits, or for
|
||||
* that matter, the DSP
|
||||
*/
|
||||
compare_len = ADDR37_IDI_LEN - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
IFDEBUG(D_ROUTE)
|
||||
int i;
|
||||
char *a, *b;
|
||||
|
||||
a = isoaa->isoa_genaddr;
|
||||
b = isoab->isoa_genaddr;
|
||||
|
||||
for (i=0; i<compare_len; i++) {
|
||||
printf("<%x=%x>", a[i]&0xff, b[i]&0xff);
|
||||
if (a[i] != b[i]) {
|
||||
printf("\naddrs are not equal at byte %d\n", i);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
printf("addrs are equal\n");
|
||||
return (1);
|
||||
ENDDEBUG
|
||||
return (!bcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len));
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_addrmatch
|
||||
*
|
||||
* PURPOSE: decide if the two sockadrr_isos passed are equal
|
||||
*
|
||||
* RETURNS: true if the addrs match, false if they do not
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
iso_addrmatch(sisoa, sisob)
|
||||
struct sockaddr_iso *sisoa, *sisob; /* addresses to check */
|
||||
{
|
||||
return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr));
|
||||
}
|
||||
#ifdef notdef
|
||||
/*
|
||||
* FUNCTION: iso_netmatch
|
||||
*
|
||||
* PURPOSE: similar to iso_addrmatch but takes sockaddr_iso
|
||||
* as argument.
|
||||
*
|
||||
* RETURNS: true if same net, false if not
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
iso_netmatch(sisoa, sisob)
|
||||
struct sockaddr_iso *sisoa, *sisob;
|
||||
{
|
||||
u_char bufa[sizeof(struct sockaddr_iso)];
|
||||
u_char bufb[sizeof(struct sockaddr_iso)];
|
||||
register int lena, lenb;
|
||||
|
||||
lena = iso_netof(&sisoa->siso_addr, bufa);
|
||||
lenb = iso_netof(&sisob->siso_addr, bufb);
|
||||
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb);
|
||||
printf("a:\n");
|
||||
dump_buf(bufa, lena);
|
||||
printf("b:\n");
|
||||
dump_buf(bufb, lenb);
|
||||
ENDDEBUG
|
||||
|
||||
return ((lena == lenb) && (!bcmp(bufa, bufb, lena)));
|
||||
}
|
||||
#endif /* notdef */
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_hashchar
|
||||
*
|
||||
* PURPOSE: Hash all character in the buffer specified into
|
||||
* a long. Return the long.
|
||||
*
|
||||
* RETURNS: The hash value.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: The hash is achieved by exclusive ORing 4 byte
|
||||
* quantities.
|
||||
*/
|
||||
u_long
|
||||
iso_hashchar(buf, len)
|
||||
register caddr_t buf; /* buffer to pack from */
|
||||
register int len; /* length of buffer */
|
||||
{
|
||||
register u_long h = 0;
|
||||
register int i;
|
||||
|
||||
for (i=0; i<len; i+=4) {
|
||||
register u_long l = 0;
|
||||
|
||||
if ((len - i) < 4) {
|
||||
/* buffer not multiple of 4 */
|
||||
switch (len - i) {
|
||||
case 3:
|
||||
l |= buf[i+2] << 8;
|
||||
case 2:
|
||||
l |= buf[i+1] << 16;
|
||||
case 1:
|
||||
l |= buf[i] << 24;
|
||||
break;
|
||||
default:
|
||||
printf("iso_hashchar: unexpected value x%x\n", len - i);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
l |= buf[i] << 24;
|
||||
l |= buf[i+1] << 16;
|
||||
l |= buf[i+2] << 8;
|
||||
l |= buf[i+3];
|
||||
}
|
||||
|
||||
h ^= l;
|
||||
}
|
||||
|
||||
h ^= (u_long) (len % 4);
|
||||
|
||||
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.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
iso_control(so, cmd, data, ifp)
|
||||
struct socket *so;
|
||||
int cmd;
|
||||
caddr_t data;
|
||||
register struct ifnet *ifp;
|
||||
{
|
||||
register struct iso_ifreq *ifr = (struct iso_ifreq *)data;
|
||||
register struct iso_ifaddr *ia = 0;
|
||||
register struct ifaddr *ifa;
|
||||
struct iso_ifaddr *oia;
|
||||
struct iso_aliasreq *ifra = (struct iso_aliasreq *)data;
|
||||
int error, hostIsNew, maskIsNew;
|
||||
|
||||
/*
|
||||
* Find address for this interface, if it exists.
|
||||
*/
|
||||
if (ifp)
|
||||
for (ia = iso_ifaddr; ia; ia = ia->ia_next)
|
||||
if (ia->ia_ifp == ifp)
|
||||
break;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case SIOCAIFADDR_ISO:
|
||||
case SIOCDIFADDR_ISO:
|
||||
if (ifra->ifra_addr.siso_family == AF_ISO)
|
||||
for (oia = ia; ia; ia = ia->ia_next) {
|
||||
if (ia->ia_ifp == ifp &&
|
||||
SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
|
||||
break;
|
||||
}
|
||||
if ((so->so_state & SS_PRIV) == 0)
|
||||
return (EPERM);
|
||||
if (ifp == 0)
|
||||
panic("iso_control");
|
||||
if (ia == (struct iso_ifaddr *)0) {
|
||||
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)
|
||||
return (ENOBUFS);
|
||||
bzero((caddr_t)nia, sizeof(*nia));
|
||||
if (ia = iso_ifaddr) {
|
||||
for ( ; ia->ia_next; ia = ia->ia_next)
|
||||
;
|
||||
ia->ia_next = nia;
|
||||
} else
|
||||
iso_ifaddr = nia;
|
||||
ia = nia;
|
||||
if (ifa = ifp->if_addrlist) {
|
||||
for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
|
||||
;
|
||||
ifa->ifa_next = (struct ifaddr *) ia;
|
||||
} else
|
||||
ifp->if_addrlist = (struct ifaddr *) ia;
|
||||
ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
|
||||
ia->ia_ifa.ifa_dstaddr
|
||||
= (struct sockaddr *)&ia->ia_dstaddr;
|
||||
ia->ia_ifa.ifa_netmask
|
||||
= (struct sockaddr *)&ia->ia_sockmask;
|
||||
ia->ia_ifp = ifp;
|
||||
if (!(ifp->if_flags & IFF_LOOPBACK))
|
||||
iso_interfaces++;
|
||||
}
|
||||
break;
|
||||
|
||||
#define cmdbyte(x) (((x) >> 8) & 0xff)
|
||||
default:
|
||||
if (cmdbyte(cmd) == 'a')
|
||||
return (snpac_ioctl(so, cmd, data));
|
||||
if (ia == (struct iso_ifaddr *)0)
|
||||
return (EADDRNOTAVAIL);
|
||||
break;
|
||||
}
|
||||
switch (cmd) {
|
||||
|
||||
case SIOCGIFADDR_ISO:
|
||||
ifr->ifr_Addr = ia->ia_addr;
|
||||
break;
|
||||
|
||||
case SIOCGIFDSTADDR_ISO:
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
|
||||
return (EINVAL);
|
||||
ifr->ifr_Addr = ia->ia_dstaddr;
|
||||
break;
|
||||
|
||||
case SIOCGIFNETMASK_ISO:
|
||||
ifr->ifr_Addr = ia->ia_sockmask;
|
||||
break;
|
||||
|
||||
case SIOCAIFADDR_ISO:
|
||||
maskIsNew = 0; hostIsNew = 1; error = 0;
|
||||
if (ia->ia_addr.siso_family == AF_ISO) {
|
||||
if (ifra->ifra_addr.siso_len == 0) {
|
||||
ifra->ifra_addr = ia->ia_addr;
|
||||
hostIsNew = 0;
|
||||
} else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
|
||||
hostIsNew = 0;
|
||||
}
|
||||
if (ifra->ifra_mask.siso_len) {
|
||||
iso_ifscrub(ifp, ia);
|
||||
ia->ia_sockmask = ifra->ifra_mask;
|
||||
maskIsNew = 1;
|
||||
}
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) &&
|
||||
(ifra->ifra_dstaddr.siso_family == AF_ISO)) {
|
||||
iso_ifscrub(ifp, ia);
|
||||
ia->ia_dstaddr = ifra->ifra_dstaddr;
|
||||
maskIsNew = 1; /* We lie; but the effect's the same */
|
||||
}
|
||||
if (ifra->ifra_addr.siso_family == AF_ISO &&
|
||||
(hostIsNew || maskIsNew)) {
|
||||
error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0);
|
||||
}
|
||||
if (ifra->ifra_snpaoffset)
|
||||
ia->ia_snpaoffset = ifra->ifra_snpaoffset;
|
||||
return (error);
|
||||
|
||||
case SIOCDIFADDR_ISO:
|
||||
iso_ifscrub(ifp, ia);
|
||||
if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
|
||||
ifp->if_addrlist = ifa->ifa_next;
|
||||
else {
|
||||
while (ifa->ifa_next &&
|
||||
(ifa->ifa_next != (struct ifaddr *)ia))
|
||||
ifa = ifa->ifa_next;
|
||||
if (ifa->ifa_next)
|
||||
ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
|
||||
else
|
||||
printf("Couldn't unlink isoifaddr from ifp\n");
|
||||
}
|
||||
oia = ia;
|
||||
if (oia == (ia = iso_ifaddr)) {
|
||||
iso_ifaddr = ia->ia_next;
|
||||
} else {
|
||||
while (ia->ia_next && (ia->ia_next != oia)) {
|
||||
ia = ia->ia_next;
|
||||
}
|
||||
if (ia->ia_next)
|
||||
ia->ia_next = oia->ia_next;
|
||||
else
|
||||
printf("Didn't unlink isoifadr from list\n");
|
||||
}
|
||||
IFAFREE((&oia->ia_ifa));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (ifp == 0 || ifp->if_ioctl == 0)
|
||||
return (EOPNOTSUPP);
|
||||
return ((*ifp->if_ioctl)(ifp, cmd, data));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete any existing route for an interface.
|
||||
*/
|
||||
iso_ifscrub(ifp, ia)
|
||||
register struct ifnet *ifp;
|
||||
register struct iso_ifaddr *ia;
|
||||
{
|
||||
int nsellength = ia->ia_addr.siso_tlen;
|
||||
if ((ia->ia_flags & IFA_ROUTE) == 0)
|
||||
return;
|
||||
ia->ia_addr.siso_tlen = 0;
|
||||
if (ifp->if_flags & IFF_LOOPBACK)
|
||||
rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
|
||||
else if (ifp->if_flags & IFF_POINTOPOINT)
|
||||
rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
|
||||
else {
|
||||
rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
|
||||
}
|
||||
ia->ia_addr.siso_tlen = nsellength;
|
||||
ia->ia_flags &= ~IFA_ROUTE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize an interface's internet address
|
||||
* and routing table entry.
|
||||
*/
|
||||
iso_ifinit(ifp, ia, siso, scrub)
|
||||
register struct ifnet *ifp;
|
||||
register struct iso_ifaddr *ia;
|
||||
struct sockaddr_iso *siso;
|
||||
{
|
||||
struct sockaddr_iso oldaddr;
|
||||
int s = splimp(), error, nsellength;
|
||||
|
||||
oldaddr = ia->ia_addr;
|
||||
ia->ia_addr = *siso;
|
||||
/*
|
||||
* Give the interface a chance to initialize
|
||||
* if this is its first address,
|
||||
* and to validate the address if necessary.
|
||||
*/
|
||||
if (ifp->if_ioctl &&
|
||||
(error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
|
||||
splx(s);
|
||||
ia->ia_addr = oldaddr;
|
||||
return (error);
|
||||
}
|
||||
if (scrub) {
|
||||
ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
|
||||
iso_ifscrub(ifp, ia);
|
||||
ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
|
||||
}
|
||||
/* XXX -- The following is here temporarily out of laziness
|
||||
in not changing every ethernet driver's if_ioctl routine */
|
||||
if (ifp->if_output == ether_output) {
|
||||
ia->ia_ifa.ifa_rtrequest = llc_rtrequest;
|
||||
ia->ia_ifa.ifa_flags |= RTF_CLONING;
|
||||
}
|
||||
/*
|
||||
* Add route for the network.
|
||||
*/
|
||||
nsellength = ia->ia_addr.siso_tlen;
|
||||
ia->ia_addr.siso_tlen = 0;
|
||||
if (ifp->if_flags & IFF_LOOPBACK) {
|
||||
ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
|
||||
error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
|
||||
} else if (ifp->if_flags & IFF_POINTOPOINT &&
|
||||
ia->ia_dstaddr.siso_family == AF_ISO)
|
||||
error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
|
||||
else {
|
||||
rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr,
|
||||
ia->ia_ifa.ifa_netmask);
|
||||
ia->ia_dstaddr.siso_nlen =
|
||||
min(ia->ia_addr.siso_nlen, (ia->ia_sockmask.siso_len - 6));
|
||||
error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
|
||||
}
|
||||
ia->ia_addr.siso_tlen = nsellength;
|
||||
ia->ia_flags |= IFA_ROUTE;
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
#ifdef notdef
|
||||
|
||||
struct ifaddr *
|
||||
iso_ifwithidi(addr)
|
||||
register struct sockaddr *addr;
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
register struct ifaddr *ifa;
|
||||
register u_int af = addr->sa_family;
|
||||
|
||||
if (af != AF_ISO)
|
||||
return (0);
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf(">>> iso_ifwithidi addr\n");
|
||||
dump_isoaddr( (struct sockaddr_iso *)(addr));
|
||||
printf("\n");
|
||||
ENDDEBUG
|
||||
for (ifp = ifnet; ifp; ifp = ifp->if_next) {
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf("iso_ifwithidi ifnet %s\n", ifp->if_name);
|
||||
ENDDEBUG
|
||||
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf("iso_ifwithidi address ");
|
||||
dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr));
|
||||
ENDDEBUG
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family)
|
||||
continue;
|
||||
|
||||
#define IFA_SIS(ifa)\
|
||||
((struct sockaddr_iso *)((ifa)->ifa_addr))
|
||||
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf(" af same, args to iso_eqtype:\n");
|
||||
printf("0x%x ", IFA_SIS(ifa)->siso_addr);
|
||||
printf(" 0x%x\n",
|
||||
&(((struct sockaddr_iso *)addr)->siso_addr));
|
||||
ENDDEBUG
|
||||
|
||||
if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr),
|
||||
&(((struct sockaddr_iso *)addr)->siso_addr))) {
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf("ifa_ifwithidi: ifa found\n");
|
||||
ENDDEBUG
|
||||
return (ifa);
|
||||
}
|
||||
IFDEBUG(D_ROUTE)
|
||||
printf(" iso_eqtype failed\n");
|
||||
ENDDEBUG
|
||||
}
|
||||
}
|
||||
return ((struct ifaddr *)0);
|
||||
}
|
||||
|
||||
#endif /* notdef */
|
||||
/*
|
||||
* FUNCTION: iso_ck_addr
|
||||
*
|
||||
* PURPOSE: return true if the iso_addr passed is
|
||||
* within the legal size limit for an iso address.
|
||||
*
|
||||
* RETURNS: true or false
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
*/
|
||||
iso_ck_addr(isoa)
|
||||
struct iso_addr *isoa; /* address to check */
|
||||
{
|
||||
return (isoa->isoa_len <= 20);
|
||||
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* FUNCTION: iso_eqtype
|
||||
*
|
||||
* PURPOSE: Determine if two iso addresses are of the same type.
|
||||
* This is flaky. Really we should consider all type 47 addrs to be the
|
||||
* same - but there do exist different structures for 47 addrs.
|
||||
* Gosip adds a 3rd.
|
||||
*
|
||||
* RETURNS: true if the addresses are the same type
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: By type, I mean rfc986, t37, or osinet
|
||||
*
|
||||
* This will first compare afis. If they match, then
|
||||
* if the addr is not t37, the idis must be compared.
|
||||
*/
|
||||
iso_eqtype(isoaa, isoab)
|
||||
struct iso_addr *isoaa; /* first addr to check */
|
||||
struct iso_addr *isoab; /* other addr to check */
|
||||
{
|
||||
if (isoaa->isoa_afi == isoab->isoa_afi) {
|
||||
if (isoaa->isoa_afi == AFI_37)
|
||||
return(1);
|
||||
else
|
||||
return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#endif /* notdef */
|
||||
/*
|
||||
* FUNCTION: iso_localifa()
|
||||
*
|
||||
* PURPOSE: Find an interface addresss having a given destination
|
||||
* or at least matching the net.
|
||||
*
|
||||
* RETURNS: ptr to an interface address
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
struct iso_ifaddr *
|
||||
iso_localifa(siso)
|
||||
register struct sockaddr_iso *siso;
|
||||
{
|
||||
register struct iso_ifaddr *ia;
|
||||
register char *cp1, *cp2, *cp3;
|
||||
register struct ifnet *ifp;
|
||||
struct iso_ifaddr *ia_maybe = 0;
|
||||
/*
|
||||
* We make one pass looking for both net matches and an exact
|
||||
* dst addr.
|
||||
*/
|
||||
for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
|
||||
if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0))
|
||||
continue;
|
||||
if (ifp->if_flags & IFF_POINTOPOINT) {
|
||||
if ((ia->ia_dstaddr.siso_family == AF_ISO) &&
|
||||
SAME_ISOADDR(&ia->ia_dstaddr, siso))
|
||||
return (ia);
|
||||
else
|
||||
if (SAME_ISOADDR(&ia->ia_addr, siso))
|
||||
ia_maybe = ia;
|
||||
continue;
|
||||
}
|
||||
if (ia->ia_sockmask.siso_len) {
|
||||
char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask;
|
||||
cp1 = ia->ia_sockmask.siso_data;
|
||||
cp2 = siso->siso_data;
|
||||
cp3 = ia->ia_addr.siso_data;
|
||||
while (cp1 < cplim)
|
||||
if (*cp1++ & (*cp2++ ^ *cp3++))
|
||||
goto next;
|
||||
ia_maybe = ia;
|
||||
}
|
||||
if (SAME_ISOADDR(&ia->ia_addr, siso))
|
||||
return ia;
|
||||
next:;
|
||||
}
|
||||
return ia_maybe;
|
||||
}
|
||||
|
||||
#ifdef TPCONS
|
||||
#include <netiso/cons.h>
|
||||
#endif /* TPCONS */
|
||||
/*
|
||||
* FUNCTION: iso_nlctloutput
|
||||
*
|
||||
* PURPOSE: Set options at the network level
|
||||
*
|
||||
* RETURNS: E*
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: This could embody some of the functions of
|
||||
* rclnp_ctloutput and cons_ctloutput.
|
||||
*/
|
||||
iso_nlctloutput(cmd, optname, pcb, m)
|
||||
int cmd; /* command:set or get */
|
||||
int optname; /* option of interest */
|
||||
caddr_t pcb; /* nl pcb */
|
||||
struct mbuf *m; /* data for set, buffer for get */
|
||||
{
|
||||
struct isopcb *isop = (struct isopcb *)pcb;
|
||||
int error = 0; /* return value */
|
||||
caddr_t data; /* data for option */
|
||||
int data_len; /* data's length */
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",
|
||||
cmd, optname, pcb, m);
|
||||
ENDDEBUG
|
||||
|
||||
if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT))
|
||||
return(EOPNOTSUPP);
|
||||
|
||||
data = mtod(m, caddr_t);
|
||||
data_len = (m)->m_len;
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_nlctloutput: data is:\n");
|
||||
dump_buf(data, data_len);
|
||||
ENDDEBUG
|
||||
|
||||
switch (optname) {
|
||||
|
||||
#ifdef TPCONS
|
||||
case CONSOPT_X25CRUD:
|
||||
if (cmd == PRCO_GETOPT) {
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data_len > MAXX25CRUDLEN) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_nlctloutput: setting x25 crud\n");
|
||||
ENDDEBUG
|
||||
|
||||
bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len);
|
||||
isop->isop_x25crud_len = data_len;
|
||||
break;
|
||||
#endif /* TPCONS */
|
||||
|
||||
default:
|
||||
error = EOPNOTSUPP;
|
||||
}
|
||||
if (cmd == PRCO_SETOPT)
|
||||
m_freem(m);
|
||||
return error;
|
||||
}
|
||||
#endif /* ISO */
|
||||
|
||||
#ifdef ARGO_DEBUG
|
||||
|
||||
/*
|
||||
* FUNCTION: dump_isoaddr
|
||||
*
|
||||
* PURPOSE: debugging
|
||||
*
|
||||
* RETURNS: nada
|
||||
*
|
||||
*/
|
||||
dump_isoaddr(s)
|
||||
struct sockaddr_iso *s;
|
||||
{
|
||||
char *clnp_saddr_isop();
|
||||
register int i;
|
||||
|
||||
if( s->siso_family == AF_ISO) {
|
||||
printf("ISO address: suffixlen %d, %s\n",
|
||||
s->siso_tlen, clnp_saddr_isop(s));
|
||||
} else if( s->siso_family == AF_INET) {
|
||||
/* hack */
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)s;
|
||||
|
||||
printf("%d.%d.%d.%d: %d",
|
||||
(sin->sin_addr.s_addr>>24)&0xff,
|
||||
(sin->sin_addr.s_addr>>16)&0xff,
|
||||
(sin->sin_addr.s_addr>>8)&0xff,
|
||||
(sin->sin_addr.s_addr)&0xff,
|
||||
sin->sin_port);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARGO_DEBUG */
|
||||
@@ -1,198 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)iso.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: iso.h,v 1.4 1995/05/30 08:10:49 rgrimes Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_ISO_H_
|
||||
#define _NETISO_ISO_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/iso.h,v 1.4 1995/05/30 08:10:49 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/iso.h,v $ */
|
||||
|
||||
/*
|
||||
* Return true if this is a multicast address
|
||||
* This assumes that the bit transmission is lsb first. This
|
||||
* assumption is valid for 802.3 but not 802.5. There is a
|
||||
* kludge to get around this for 802.5 -- see if_lan.c
|
||||
* where subnetwork header is setup.
|
||||
*/
|
||||
#define IS_MULTICAST(snpa)\
|
||||
((snpa)[0] & 0x01)
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
#define ISOPROTO_TP3 28 /* not implemented */
|
||||
#define ISOPROTO_TP4 29 /* connection oriented transport protocol */
|
||||
#define ISOPROTO_TP ISOPROTO_TP4 /* tp-4 with negotiation */
|
||||
#define ISOPROTO_CLTP 30 /* connectionless transport (not yet impl.) */
|
||||
#define ISOPROTO_CLNP 31 /* connectionless internetworking protocol */
|
||||
#define ISOPROTO_X25 32 /* cons */
|
||||
#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
|
||||
|
||||
#define ISO_PORT_RESERVED 1024
|
||||
#define ISO_PORT_USERRESERVED 5000
|
||||
/*
|
||||
* Port/socket numbers: standard network functions
|
||||
* NOT PRESENTLY USED
|
||||
*/
|
||||
#define ISO_PORT_MAINT 501
|
||||
#define ISO_PORT_ECHO 507
|
||||
#define ISO_PORT_DISCARD 509
|
||||
#define ISO_PORT_SYSTAT 511
|
||||
#define ISO_PORT_NETSTAT 515
|
||||
/*
|
||||
* Port/socket numbers: non-standard application functions
|
||||
*/
|
||||
#define ISO_PORT_LOGIN 513
|
||||
/*
|
||||
* Port/socket numbers: public use
|
||||
*/
|
||||
#define ISO_PORT_PUBLIC 1024 /* high bit set --> public */
|
||||
|
||||
/*
|
||||
* Network layer protocol identifiers
|
||||
*/
|
||||
#define ISO8473_CLNP 0x81
|
||||
#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 */
|
||||
|
||||
|
||||
|
||||
/* The following looks like a sockaddr
|
||||
* to facilitate using tree lookup routines */
|
||||
struct iso_addr {
|
||||
u_char isoa_len; /* length (in bytes) */
|
||||
char isoa_genaddr[20]; /* general opaque address */
|
||||
};
|
||||
|
||||
struct sockaddr_iso {
|
||||
u_char siso_len; /* length */
|
||||
u_char siso_family; /* family */
|
||||
u_char siso_plen; /* presentation selector length */
|
||||
u_char siso_slen; /* session selector length */
|
||||
u_char siso_tlen; /* transport selector length */
|
||||
struct iso_addr siso_addr; /* network address */
|
||||
u_char siso_pad[6]; /* space for gosip v2 sels */
|
||||
/* makes struct 32 bytes long */
|
||||
};
|
||||
#define siso_nlen siso_addr.isoa_len
|
||||
#define siso_data siso_addr.isoa_genaddr
|
||||
|
||||
#define TSEL(s) ((caddr_t)((s)->siso_data + (s)->siso_nlen))
|
||||
|
||||
#define SAME_ISOADDR(a, b) \
|
||||
(bcmp((a)->siso_data, (b)->siso_data, (unsigned)(a)->siso_nlen)==0)
|
||||
/*
|
||||
* The following are specific values for siso->siso_data[0],
|
||||
* otherwise known as the AFI:
|
||||
*/
|
||||
#define AFI_37 0x37 /* bcd of "37" */
|
||||
#define AFI_OSINET 0x47 /* bcd of "47" */
|
||||
#define AFI_RFC986 0x47 /* bcd of "47" */
|
||||
#define AFI_SNA 0x00 /* SubNetwork Address; invalid really...*/
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
struct afhash;
|
||||
|
||||
int iso_netmatch __P((struct sockaddr_iso *sisoa, struct sockaddr_iso *sisob));
|
||||
int iso_hash __P((struct sockaddr_iso *siso, struct afhash *hp));
|
||||
int iso_addrmatch __P((struct sockaddr_iso *sisoa, struct sockaddr_iso *sisob));
|
||||
extern struct domain isodomain;
|
||||
extern struct protosw isosw[];
|
||||
|
||||
#else
|
||||
/* user utilities definitions from the iso library */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
struct iso_addr *iso_addr __P((const char *));
|
||||
char *iso_ntoa __P((const struct iso_addr *));
|
||||
|
||||
/* THESE DON'T EXIST YET */
|
||||
struct hostent *iso_gethostbyname(), *iso_gethostbyaddr();
|
||||
__END_DECLS
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
|
||||
|
||||
#endif
|
||||
@@ -1,361 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)iso_chksum.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: iso_chksum.c,v 1.2 1994/08/02 07:50:31 davidg Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* $Header: /home/ncvs/src/sys/netiso/iso_chksum.c,v 1.2 1994/08/02 07:50:31 davidg Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/iso_chksum.c,v $
|
||||
*
|
||||
* ISO CHECKSUM
|
||||
*
|
||||
* The checksum generation and check routines are here.
|
||||
* The checksum is 2 bytes such that the sum of all the bytes b(i) == 0
|
||||
* and the sum of i * b(i) == 0.
|
||||
* The whole thing is complicated by the fact that the data are in mbuf
|
||||
* chains.
|
||||
* Furthermore, there is the possibility of wraparound in the running
|
||||
* sums after adding up 4102 octets. In order to avoid doing a mod
|
||||
* operation after EACH add, we have restricted this implementation to
|
||||
* negotiating a maximum of 4096-octets per TPDU (for the transport layer).
|
||||
* The routine iso_check_csum doesn't need to know where the checksum
|
||||
* octets are.
|
||||
* The routine iso_gen_csum takes a pointer to an mbuf chain (logically
|
||||
* a chunk of data), an offset into the chunk at which the 2 octets are to
|
||||
* be stuffed, and the length of the chunk. The 2 octets have to be
|
||||
* logically adjacent, but may be physically located in separate mbufs.
|
||||
*/
|
||||
|
||||
#ifdef ISO
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#endif /* ISO */
|
||||
|
||||
#ifndef MNULL
|
||||
#define MNULL (struct mbuf *)0
|
||||
#endif /* MNULL */
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_check_csum
|
||||
*
|
||||
* PURPOSE: To check the checksum of the packet in the mbuf chain (m).
|
||||
* The total length of the packet is (len).
|
||||
* Called from tp_input() and clnp_intr()
|
||||
*
|
||||
* RETURNS: TRUE (something non-zero) if there is a checksum error,
|
||||
* FALSE if there was NO checksum error.
|
||||
*
|
||||
* SIDE EFFECTS: none
|
||||
*
|
||||
* NOTES: It might be possible to gain something by optimizing
|
||||
* this routine (unrolling loops, etc). But it is such
|
||||
* a horrible thing to fiddle with anyway, it probably
|
||||
* isn't worth it.
|
||||
*/
|
||||
int
|
||||
iso_check_csum(m, len)
|
||||
struct mbuf *m;
|
||||
int len;
|
||||
{
|
||||
register u_char *p = mtod(m, u_char *);
|
||||
register u_long c0=0, c1=0;
|
||||
register int i=0;
|
||||
int cum = 0; /* cumulative length */
|
||||
int l;
|
||||
|
||||
l = len;
|
||||
len = min(m->m_len, len);
|
||||
i = 0;
|
||||
|
||||
IFDEBUG(D_CHKSUM)
|
||||
printf("iso_check_csum: m x%x, l x%x, m->m_len x%x\n", m, l, m->m_len);
|
||||
ENDDEBUG
|
||||
|
||||
while( i<l ) {
|
||||
cum += len;
|
||||
while (i<cum) {
|
||||
c0 = c0 + *(p++);
|
||||
c1 += c0;
|
||||
i++;
|
||||
}
|
||||
if(i < l) {
|
||||
m = m->m_next;
|
||||
IFDEBUG(D_CHKSUM)
|
||||
printf("iso_check_csum: new mbuf\n");
|
||||
if(l-i < m->m_len)
|
||||
printf(
|
||||
"bad mbuf chain in check csum l 0x%x i 0x%x m_data 0x%x",
|
||||
l,i,m->m_data);
|
||||
ENDDEBUG
|
||||
ASSERT( m != MNULL);
|
||||
len = min( m->m_len, l-i);
|
||||
p = mtod(m, u_char *);
|
||||
}
|
||||
}
|
||||
if ( ((int)c0 % 255) || ((int)c1 % 255) ) {
|
||||
IFDEBUG(D_CHKSUM)
|
||||
printf("BAD iso_check_csum l 0x%x cum 0x%x len 0x%x, i 0x%x",
|
||||
l, cum, len, i);
|
||||
ENDDEBUG
|
||||
return ((int)c0 % 255)<<8 | ((int)c1 % 255);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_gen_csum
|
||||
*
|
||||
* PURPOSE: To generate the checksum of the packet in the mbuf chain (m).
|
||||
* The first of the 2 (logically) adjacent checksum bytes
|
||||
* (x and y) go at offset (n).
|
||||
* (n) is an offset relative to the beginning of the data,
|
||||
* not the beginning of the mbuf.
|
||||
* (l) is the length of the total mbuf chain's data.
|
||||
* Called from tp_emit(), tp_error_emit()
|
||||
* clnp_emit_er(), clnp_forward(), clnp_output().
|
||||
*
|
||||
* RETURNS: Rien
|
||||
*
|
||||
* SIDE EFFECTS: Puts the 2 checksum bytes into the packet.
|
||||
*
|
||||
* NOTES: Ditto the note for iso_check_csum().
|
||||
*/
|
||||
|
||||
void
|
||||
iso_gen_csum(m,n,l)
|
||||
struct mbuf *m;
|
||||
int n; /* offset of 2 checksum bytes */
|
||||
int l;
|
||||
{
|
||||
register u_char *p = mtod(m, u_char *);
|
||||
register int c0=0, c1=0;
|
||||
register int i=0;
|
||||
int loc = n++, len=0; /* n is position, loc is offset */
|
||||
u_char *xloc;
|
||||
u_char *yloc;
|
||||
int cum=0; /* cum == cumulative length */
|
||||
|
||||
IFDEBUG(D_CHKSUM)
|
||||
printf("enter gen csum m 0x%x n 0x%x l 0x%x\n",m, n-1 ,l );
|
||||
ENDDEBUG
|
||||
|
||||
while(i < l) {
|
||||
len = min(m->m_len, CLBYTES);
|
||||
/* RAH: don't cksum more than l bytes */
|
||||
len = min(len, l - i);
|
||||
|
||||
cum +=len;
|
||||
p = mtod(m, u_char *);
|
||||
|
||||
if(loc>=0) {
|
||||
if (loc < len) {
|
||||
xloc = loc + mtod(m, u_char *);
|
||||
IFDEBUG(D_CHKSUM)
|
||||
printf("1: zeroing xloc 0x%x loc 0x%x\n",xloc, loc );
|
||||
ENDDEBUG
|
||||
*xloc = (u_char)0;
|
||||
if (loc+1 < len) {
|
||||
/* both xloc and yloc are in same mbuf */
|
||||
yloc = 1 + xloc;
|
||||
IFDEBUG(D_CHKSUM)
|
||||
printf("2: zeroing yloc 0x%x loc 0x%x\n",yloc, loc );
|
||||
ENDDEBUG
|
||||
*yloc = (u_char)0;
|
||||
} else {
|
||||
/* crosses boundary of mbufs */
|
||||
yloc = mtod(m->m_next, u_char *);
|
||||
IFDEBUG(D_CHKSUM)
|
||||
printf("3: zeroing yloc 0x%x \n",yloc );
|
||||
ENDDEBUG
|
||||
*yloc = (u_char)0;
|
||||
}
|
||||
}
|
||||
loc -= len;
|
||||
}
|
||||
|
||||
while(i < cum) {
|
||||
c0 = (c0 + *p);
|
||||
c1 += c0 ;
|
||||
i++;
|
||||
p++;
|
||||
}
|
||||
m = m->m_next;
|
||||
}
|
||||
IFDEBUG(D_CHKSUM)
|
||||
printf("gen csum final xloc 0x%x yloc 0x%x\n",xloc, yloc );
|
||||
ENDDEBUG
|
||||
|
||||
c1 = (((c0 * (l-n))-c1)%255) ;
|
||||
*xloc = (u_char) ((c1 < 0)? c1+255 : c1);
|
||||
|
||||
c1 = (-(int)(c1+c0))%255;
|
||||
*yloc = (u_char) (c1 < 0? c1 + 255 : c1);
|
||||
|
||||
IFDEBUG(D_CHKSUM)
|
||||
printf("gen csum end \n");
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: m_datalen
|
||||
*
|
||||
* PURPOSE: returns length of the mbuf chain.
|
||||
* used all over the iso code.
|
||||
*
|
||||
* RETURNS: integer
|
||||
*
|
||||
* SIDE EFFECTS: none
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
|
||||
int
|
||||
m_datalen (m)
|
||||
register struct mbuf *m;
|
||||
{
|
||||
register int datalen;
|
||||
|
||||
for (datalen = 0; m; m = m->m_next)
|
||||
datalen += m->m_len;
|
||||
return datalen;
|
||||
}
|
||||
|
||||
int
|
||||
m_compress(in, out)
|
||||
register struct mbuf *in, **out;
|
||||
{
|
||||
register int datalen = 0;
|
||||
int s = splimp();
|
||||
|
||||
if( in->m_next == MNULL ) {
|
||||
*out = in;
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("m_compress returning 0x%x: A\n", in->m_len);
|
||||
ENDDEBUG
|
||||
splx(s);
|
||||
return in->m_len;
|
||||
}
|
||||
MGET((*out), M_DONTWAIT, MT_DATA);
|
||||
if((*out) == MNULL) {
|
||||
*out = in;
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("m_compress returning -1: B\n");
|
||||
ENDDEBUG
|
||||
splx(s);
|
||||
return -1;
|
||||
}
|
||||
(*out)->m_len = 0;
|
||||
(*out)->m_act = MNULL;
|
||||
|
||||
while (in) {
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("m_compress in 0x%x *out 0x%x\n", in, *out);
|
||||
printf("m_compress in: len 0x%x, off 0x%x\n", in->m_len, in->m_data);
|
||||
printf("m_compress *out: len 0x%x, off 0x%x\n", (*out)->m_len,
|
||||
(*out)->m_data);
|
||||
ENDDEBUG
|
||||
if (in->m_flags & M_EXT) {
|
||||
ASSERT(in->m_len == 0);
|
||||
}
|
||||
if ( in->m_len == 0) {
|
||||
in = in->m_next;
|
||||
continue;
|
||||
}
|
||||
if (((*out)->m_flags & M_EXT) == 0) {
|
||||
int len;
|
||||
|
||||
len = M_TRAILINGSPACE(*out);
|
||||
len = min(len, in->m_len);
|
||||
datalen += len;
|
||||
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("m_compress copying len %d\n", len);
|
||||
ENDDEBUG
|
||||
bcopy(mtod(in, caddr_t), mtod((*out), caddr_t) + (*out)->m_len,
|
||||
(unsigned)len);
|
||||
|
||||
(*out)->m_len += len;
|
||||
in->m_len -= len;
|
||||
continue;
|
||||
} else {
|
||||
/* (*out) is full */
|
||||
if(( (*out)->m_next = m_get(M_DONTWAIT, MT_DATA) ) == MNULL) {
|
||||
m_freem(*out);
|
||||
*out = in;
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("m_compress returning -1: B\n");
|
||||
ENDDEBUG
|
||||
splx(s);
|
||||
return -1;
|
||||
}
|
||||
(*out)->m_len = 0;
|
||||
(*out)->m_act = MNULL;
|
||||
*out = (*out)->m_next;
|
||||
}
|
||||
}
|
||||
m_freem(in);
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("m_compress returning 0x%x: A\n", datalen);
|
||||
ENDDEBUG
|
||||
splx(s);
|
||||
return datalen;
|
||||
}
|
||||
@@ -1,275 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)iso_errno.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: iso_errno.h,v 1.4 1994/11/27 20:58:30 ats Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_ISO_ERRNO_H_
|
||||
#define _NETISO_ISO_ERRNO_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
|
||||
#define ISO_ERROR_MASK 0x8000
|
||||
#define BSD_ERROR_MASK 0x0000
|
||||
#define TP_ERROR_MASK 0x8800 /* transport layer */
|
||||
#define CONL_ERROR_MASK 0x8400 /* co network layer */
|
||||
#define CLNL_ERROR_MASK 0x8200 /* cl network layer */
|
||||
#define TP_ERROR_SNDC 0x10000 /* kludge to force DC's on certain errors */
|
||||
|
||||
#define E_CO_NOERROR (CONL_ERROR_MASK | 0x0) /* no add'l info */
|
||||
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Transport Layer */
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
|
||||
#define E_TP_DR_NO_REAS (TP_ERROR_MASK | 0x0) /* dr reason not specified*/
|
||||
#define E_TP_CONGEST (TP_ERROR_MASK | 0x1) /* dr reason congestion */
|
||||
#define E_TP_NO_SESSION (TP_ERROR_MASK | 0x2) /* dr reason no sess ent */
|
||||
#define E_TP_ADDR_UNK (TP_ERROR_MASK | 0x3) /* dr reason addr unknown */
|
||||
|
||||
#define E_TP_ER_NO_REAS (TP_ERROR_MASK | 0x40) /* er reas not specified */
|
||||
#define E_TP_INV_PCODE (TP_ERROR_MASK | 0x41) /* er reas invalid parm code */
|
||||
#define E_TP_INV_TPDU (TP_ERROR_MASK | 0x42) /* er reas invalid tpdu type */
|
||||
#define E_TP_INV_PVAL (TP_ERROR_MASK | 0x43) /* er reas invalid parm value*/
|
||||
|
||||
#define E_TP_NORMAL_DISC (TP_ERROR_MASK | 0x80) /* dr reas normal disc */
|
||||
#define E_TP_CONGEST_2 (TP_ERROR_MASK | 0x81) /* dr reason congestion */
|
||||
#define E_TP_NEGOT_FAILED (TP_ERROR_MASK | 0x82) /* dr negotiation failed */
|
||||
#define E_TP_DUPL_SRCREF (TP_ERROR_MASK | 0x83) /* dr duplicate src ref */
|
||||
#define E_TP_MISM_REFS (TP_ERROR_MASK | 0x84) /* dr mismatched references*/
|
||||
#define E_TP_PROTO_ERR (TP_ERROR_MASK | 0x85) /* dr protocol error*/
|
||||
/* 0x86 not used */
|
||||
#define E_TP_REF_OVERFLOW (TP_ERROR_MASK | 0x87) /* dr reference overflow */
|
||||
#define E_TP_NO_CR_ON_NC (TP_ERROR_MASK | 0x88) /* dr cr refused on this nc */
|
||||
/* 0x89 not used */
|
||||
#define E_TP_LENGTH_INVAL (TP_ERROR_MASK | 0x8a) /* dr inval length in hdr*/
|
||||
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Connection Less Network Layer */
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
|
||||
/* #define E_CLNL_??? (CLNL_ERROR_MASK | 0x1) explanation */
|
||||
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Connection Oriented Network Layer */
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
/* see p. 149 of ISO 8208 */
|
||||
#define E_CO_NOERROR (CONL_ERROR_MASK | 0x0) /* no add'l info */
|
||||
#define E_CO_INV_PS (CONL_ERROR_MASK | 0x1) /* invalid p(s) */
|
||||
#define E_CO_INV_PR (CONL_ERROR_MASK | 0x2) /* invalid p(r) */
|
||||
/* dot dot dot */
|
||||
#define E_CO_INV_PKT_TYPE (CONL_ERROR_MASK | 0x10) /* packet type invalid*/
|
||||
#define E_CO_INV_PKT_R1 (CONL_ERROR_MASK | 0x11) /* for state r1 */
|
||||
#define E_CO_INV_PKT_R2 (CONL_ERROR_MASK | 0x12) /* for state r2 */
|
||||
#define E_CO_INV_PKT_R3 (CONL_ERROR_MASK | 0x13) /* for state r3 */
|
||||
#define E_CO_INV_PKT_P1 (CONL_ERROR_MASK | 0x14) /* for state p1 */
|
||||
#define E_CO_INV_PKT_P2 (CONL_ERROR_MASK | 0x15) /* for state p2 */
|
||||
#define E_CO_INV_PKT_P3 (CONL_ERROR_MASK | 0x16) /* for state p3 */
|
||||
#define E_CO_INV_PKT_P4 (CONL_ERROR_MASK | 0x17) /* for state p4 */
|
||||
#define E_CO_INV_PKT_P5 (CONL_ERROR_MASK | 0x18) /* for state p5 */
|
||||
#define E_CO_INV_PKT_P6 (CONL_ERROR_MASK | 0x19) /* for state p6 */
|
||||
#define E_CO_INV_PKT_P7 (CONL_ERROR_MASK | 0x1a) /* for state p7 */
|
||||
#define E_CO_INV_PKT_D1 (CONL_ERROR_MASK | 0x1b) /* for state d1 */
|
||||
#define E_CO_INV_PKT_D2 (CONL_ERROR_MASK | 0x1c) /* for state d2 */
|
||||
#define E_CO_INV_PKT_D3 (CONL_ERROR_MASK | 0x1d) /* for state d3 */
|
||||
/* dot dot dot */
|
||||
#define E_CO_PKT_NOT_ALWD (CONL_ERROR_MASK | 0x20) /* packet not allowed */
|
||||
#define E_CO_PNA_UNIDENT (CONL_ERROR_MASK | 0x21) /* unidentifiable pkt */
|
||||
#define E_CO_PNA_ONEWAY (CONL_ERROR_MASK | 0x22) /* call on 1-way lc */
|
||||
#define E_CO_PNA_PVC (CONL_ERROR_MASK | 0x23) /* inv pkt type on a pvc */
|
||||
#define E_CO_PNA_UNASSLC (CONL_ERROR_MASK | 0x24) /* pkt on unassigned lc */
|
||||
#define E_CO_PNA_REJECT (CONL_ERROR_MASK | 0x25) /* REJ not subscribed to*/
|
||||
#define E_CO_PNA_SHORT (CONL_ERROR_MASK | 0x26) /* pkt too short */
|
||||
#define E_CO_PNA_LONG (CONL_ERROR_MASK | 0x27) /* pkt too long */
|
||||
#define E_CO_PNA_INVGFI (CONL_ERROR_MASK | 0x28) /* inv gen format id */
|
||||
#define E_CO_PNA_NZLCI (CONL_ERROR_MASK | 0x29) \
|
||||
/* restart or reg pkt with nonzero logical channel identifier */
|
||||
#define E_CO_PNA_FACIL (CONL_ERROR_MASK | 0x2a) \
|
||||
/* pkt type not compat with facility */
|
||||
#define E_CO_PNA_UINTCON (CONL_ERROR_MASK | 0x2b) /* unauthor intrpt conf */
|
||||
#define E_CO_PNA_UINTRPT (CONL_ERROR_MASK | 0x2c) /* unauthorized intrpt */
|
||||
#define E_CO_PNA_UREJECT (CONL_ERROR_MASK | 0x2d) /* unauthorized reject */
|
||||
|
||||
#define E_CO_TMR_EXP (CONL_ERROR_MASK | 0x30) /* timer expired */
|
||||
#define E_CO_TMR_CALR (CONL_ERROR_MASK | 0x31) /* inc. call or call req */
|
||||
#define E_CO_TMR_CLRI (CONL_ERROR_MASK | 0x32) /* clear indication */
|
||||
#define E_CO_TMR_RSTI (CONL_ERROR_MASK | 0x33) /* reset indication */
|
||||
#define E_CO_TMR_RRTI (CONL_ERROR_MASK | 0x34) /* restart indication */
|
||||
|
||||
#define E_CO_REG_PROB (CONL_ERROR_MASK | 0x40)\
|
||||
/* call setup, clear, or registration problem */
|
||||
#define E_CO_REG_CODE (CONL_ERROR_MASK | 0x41) /* code not allowed */
|
||||
#define E_CO_REG_PARM (CONL_ERROR_MASK | 0x42) /* parameter not allowed */
|
||||
#define E_CO_REG_ICDA (CONL_ERROR_MASK | 0x43) /* invalid called addr */
|
||||
#define E_CO_REG_ICGA (CONL_ERROR_MASK | 0x44) /* invalid calling addr */
|
||||
#define E_CO_REG_ILEN (CONL_ERROR_MASK | 0x45) /* invalid facil length */
|
||||
#define E_CO_REG_IBAR (CONL_ERROR_MASK | 0x46) /* incoming call barred */
|
||||
#define E_CO_REG_NOLC (CONL_ERROR_MASK | 0x47) /* no logical chan avail*/
|
||||
#define E_CO_REG_COLL (CONL_ERROR_MASK | 0x48) /* call collision */
|
||||
#define E_CO_REG_DUPF (CONL_ERROR_MASK | 0x49) /* dupl facil requested */
|
||||
#define E_CO_REG_NZAL (CONL_ERROR_MASK | 0x4a) /* non-zero addr length */
|
||||
#define E_CO_REG_NZFL (CONL_ERROR_MASK | 0x4b) /* non-zero facil length */
|
||||
#define E_CO_REG_EFNP (CONL_ERROR_MASK | 0x4c) \
|
||||
/* expected facil not provided */
|
||||
#define E_CO_REG_ICCITT (CONL_ERROR_MASK | 0x4d) \
|
||||
/* invalid CCITT-specified DTE facil */
|
||||
|
||||
#define E_CO_MISC (CONL_ERROR_MASK | 0x50) /* miscellaneous */
|
||||
#define E_CO_MISC_CAUSE (CONL_ERROR_MASK | 0x51) /* improper cause code */
|
||||
#define E_CO_MISC_ALIGN (CONL_ERROR_MASK | 0x52) /* not octet-aligned */
|
||||
#define E_CO_MISC_IQBS (CONL_ERROR_MASK | 0x53) \
|
||||
/* inconsistent Q bit settings */
|
||||
|
||||
#define E_CO_INTL (CONL_ERROR_MASK | 0x70) /* international problem */
|
||||
#define E_CO_IREMNWK (CONL_ERROR_MASK | 0x71) /* remote network problem */
|
||||
#define E_CO_INPROTO (CONL_ERROR_MASK | 0x72) /* int'l protocol problem */
|
||||
#define E_CO_ILINKDWN (CONL_ERROR_MASK | 0x73) /* int'l link down */
|
||||
#define E_CO_ILINKBSY (CONL_ERROR_MASK | 0x74) /* int'l link busy */
|
||||
#define E_CO_IXNETFAC (CONL_ERROR_MASK | 0x75) /* transit netwk facil */
|
||||
#define E_CO_IRNETFAC (CONL_ERROR_MASK | 0x76) /* remote netwk facil */
|
||||
#define E_CO_IROUTING (CONL_ERROR_MASK | 0x77) /* int'l routing prob */
|
||||
#define E_CO_ITMPRTG (CONL_ERROR_MASK | 0x78) /* temporary routing prob */
|
||||
#define E_CO_IUNKDNIC (CONL_ERROR_MASK | 0x79) /* unknown called DNIC */
|
||||
#define E_CO_IMAINT (CONL_ERROR_MASK | 0x7a) /* maintenance action */
|
||||
|
||||
#define E_CO_TIMO (CONL_ERROR_MASK | 0x90) \
|
||||
/* timer expired or retransmission count surpassed */
|
||||
#define E_CO_TIM_INTRP (CONL_ERROR_MASK | 0x91) /* for interrupt */
|
||||
#define E_CO_TIM_DATA (CONL_ERROR_MASK | 0x92) /* for data */
|
||||
#define E_CO_TIM_REJ (CONL_ERROR_MASK | 0x93) /* for reject */
|
||||
|
||||
#define E_CO_DTE_SPEC (CONL_ERROR_MASK | 0xa0) /* DTE-specific */
|
||||
#define E_CO_DTE_OK (CONL_ERROR_MASK | 0xa1) /* DTE operational */
|
||||
#define E_CO_DTE_NOK (CONL_ERROR_MASK | 0xa2) /* DTE not operational */
|
||||
#define E_CO_DTE_RSRC (CONL_ERROR_MASK | 0xa3) /* DTE resource constraint*/
|
||||
#define E_CO_DTE_FSLCT (CONL_ERROR_MASK | 0xa4) /* fast select not subsc */
|
||||
#define E_CO_DTE_PFPKT (CONL_ERROR_MASK | 0xa5) /* partially full pkt */
|
||||
#define E_CO_DTE_DBIT (CONL_ERROR_MASK | 0xa6) /* D-bit proc not supp */
|
||||
#define E_CO_DTE_RCCON (CONL_ERROR_MASK | 0xa7) /* reg/canell confirmed */
|
||||
|
||||
#define E_CO_OSI_NSP (CONL_ERROR_MASK | 0xe0) /* OSI net svc problem */
|
||||
#define E_CO_OSI_DISCT (CONL_ERROR_MASK | 0xe1) /* disconnect transient */
|
||||
#define E_CO_OSI_DISCP (CONL_ERROR_MASK | 0xe2) /* disconnect permanent */
|
||||
#define E_CO_OSI_REJT (CONL_ERROR_MASK | 0xe3) /* reject transient */
|
||||
#define E_CO_OSI_REJP (CONL_ERROR_MASK | 0xe4) /* reject permanent */
|
||||
#define E_CO_OSI_QOST (CONL_ERROR_MASK | 0xe5) /* reject QOS transient */
|
||||
#define E_CO_OSI_QOSP (CONL_ERROR_MASK | 0xe6) /* reject QOS permanent */
|
||||
#define E_CO_OSI_NSAPT (CONL_ERROR_MASK | 0xe7) /* NSAP unreach transient */
|
||||
#define E_CO_OSI_NSAPP (CONL_ERROR_MASK | 0xe8) /* NSAP unreach permanent */
|
||||
#define E_CO_OSI_RESET (CONL_ERROR_MASK | 0xe9) /* reset no reason */
|
||||
#define E_CO_OSI_CONGEST (CONL_ERROR_MASK | 0xea) /* reset congestion */
|
||||
#define E_CO_OSI_UNSAP (CONL_ERROR_MASK | 0xeb) /* unknown NSAP permanent */
|
||||
|
||||
#define E_CO_HLI_INIT (CONL_ERROR_MASK | 0xf0) /* higher level initiated*/
|
||||
#define E_CO_HLI_DISCN (CONL_ERROR_MASK | 0xf1) /* disconnect normal */
|
||||
#define E_CO_HLI_DISCA (CONL_ERROR_MASK | 0xf2) /* disconnect abnormal */
|
||||
#define E_CO_HLI_DISCI (CONL_ERROR_MASK | 0xf3) /* disconnect incompatible*/
|
||||
#define E_CO_HLI_REJT (CONL_ERROR_MASK | 0xf4) /* reject transient */
|
||||
#define E_CO_HLI_REJP (CONL_ERROR_MASK | 0xf5) /* reject permanent */
|
||||
#define E_CO_HLI_QOST (CONL_ERROR_MASK | 0xf6) /* reject QOS transient */
|
||||
#define E_CO_HLI_QOSP (CONL_ERROR_MASK | 0xf7) /* reject QOS permanent */
|
||||
#define E_CO_HLI_REJI (CONL_ERROR_MASK | 0xf8) /* reject incompatible */
|
||||
#define E_CO_HLI_PROTOID (CONL_ERROR_MASK | 0xf9) /* unrecog proto id */
|
||||
#define E_CO_HLI_RESYNC (CONL_ERROR_MASK | 0xfa) /* reset - user resync */
|
||||
|
||||
/* Cause on 8208 CLEAR field */
|
||||
#define E_CO_NUMBERBUSY (CONL_ERROR_MASK | 0x101) /* Number busy */
|
||||
#define E_CO_INVFACREQ (CONL_ERROR_MASK | 0x103) /* invalid facil req */
|
||||
#define E_CO_NETCONGEST (CONL_ERROR_MASK | 0x105) /* Network congestion */
|
||||
#define E_CO_OUTOFORDER (CONL_ERROR_MASK | 0x109) /* Out of order */
|
||||
#define E_CO_ACCESSBAR (CONL_ERROR_MASK | 0x10b) /* access barred */
|
||||
#define E_CO_NOTOBTAIN (CONL_ERROR_MASK | 0x10d) /* not obtainable */
|
||||
#define E_CO_REMPROCERR (CONL_ERROR_MASK | 0x111) /* Remote procedure err */
|
||||
#define E_CO_LOCPROCERR (CONL_ERROR_MASK | 0x113) /* Local procedure err */
|
||||
#define E_CO_RPOAOOO (CONL_ERROR_MASK | 0x115) /* RPOA out of order */
|
||||
#define E_CO_NOREVCHG (CONL_ERROR_MASK | 0x119) /* Revs chg not accepted*/
|
||||
#define E_CO_INCOMPAT (CONL_ERROR_MASK | 0x121) /* Incompatible dest */
|
||||
#define E_CO_NOFASTSEL (CONL_ERROR_MASK | 0x129)
|
||||
/* Fast select accpt not subscribed */
|
||||
#define E_CO_NOSHIP (CONL_ERROR_MASK | 0x139) /* ship absent */
|
||||
#define E_CO_GWPROCERR (CONL_ERROR_MASK | 0x1c1) /* Gateway-detected err*/
|
||||
#define E_CO_GWCONGEST (CONL_ERROR_MASK | 0x1c3) /* Gateway congestion*/
|
||||
|
||||
/* ARGO only */
|
||||
#define E_CO_QFULL (CONL_ERROR_MASK | 0x100) /* dropped packet - queue full*/
|
||||
#define E_CO_AIWP (CONL_ERROR_MASK | 0x102) /* addr incompat w/proto */
|
||||
#define E_CO_CHAN (CONL_ERROR_MASK | 0x104) /* bad channel number */
|
||||
|
||||
/* ARGO only; driver specific */
|
||||
#define E_CO_NORESOURCES (CONL_ERROR_MASK | 0x1b0) /* eicon clogged */
|
||||
#define E_CO_PDNDOWN (CONL_ERROR_MASK | 0x1b1) /* physical net down */
|
||||
#define E_CO_DRVRCLRESET (CONL_ERROR_MASK | 0x1b2) /* driver clear/reset */
|
||||
#define E_CO_PDNCLRESET (CONL_ERROR_MASK | 0x1b3) /* PDN clear/reset */
|
||||
#define E_CO_DTECLRESET (CONL_ERROR_MASK | 0x1b4) /* board clear/reset */
|
||||
#define E_CO_UNKCLRESET (CONL_ERROR_MASK | 0x1b5) /* unexpected clr/rst */
|
||||
|
||||
#define CONL_ERROR_MAX 0x1c3
|
||||
|
||||
#endif
|
||||
@@ -1,618 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)iso_pcb.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: iso_pcb.c,v 1.2 1994/08/02 07:50:37 davidg Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* $Header: /home/ncvs/src/sys/netiso/iso_pcb.c,v 1.2 1994/08/02 07:50:37 davidg Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/iso_pcb.c,v $
|
||||
*
|
||||
* Iso address family net-layer(s) pcb stuff. NEH 1/29/87
|
||||
*/
|
||||
|
||||
#ifdef ISO
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.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>
|
||||
#include <netccitt/pk.h>
|
||||
#include <netccitt/pk_var.h>
|
||||
#endif
|
||||
|
||||
#define PCBNULL (struct isopcb *)0
|
||||
struct iso_addr zeroiso_addr = {
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_pcballoc
|
||||
*
|
||||
* PURPOSE: creates an isopcb structure in an mbuf,
|
||||
* with socket (so), and
|
||||
* puts it in the queue with head (head)
|
||||
*
|
||||
* RETURNS: 0 if OK, ENOBUFS if can't alloc the necessary mbuf
|
||||
*/
|
||||
int
|
||||
iso_pcballoc(so, head)
|
||||
struct socket *so;
|
||||
struct isopcb *head;
|
||||
{
|
||||
register struct isopcb *isop;
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcballoc(so 0x%x)\n", so);
|
||||
ENDDEBUG
|
||||
MALLOC(isop, struct isopcb *, sizeof(*isop), M_PCB, M_NOWAIT);
|
||||
if (isop == NULL)
|
||||
return ENOBUFS;
|
||||
bzero((caddr_t)isop, sizeof(*isop));
|
||||
isop->isop_head = head;
|
||||
isop->isop_socket = so;
|
||||
insque(isop, head);
|
||||
if (so)
|
||||
so->so_pcb = (caddr_t)isop;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_pcbbind
|
||||
*
|
||||
* PURPOSE: binds the address given in *(nam) to the socket
|
||||
* specified by the isopcb in *(isop)
|
||||
* If the given address is zero, it makes sure the
|
||||
* address isn't already in use and if it's got a network
|
||||
* portion, we look for an interface with that network
|
||||
* address. If the address given is zero, we allocate
|
||||
* a port and stuff it in the (nam) structure.
|
||||
*
|
||||
* RETURNS: errno E* or 0 if ok.
|
||||
*
|
||||
* SIDE EFFECTS: increments head->isop_lport if it allocates a port #
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
#define satosiso(sa) ((struct sockaddr_iso *)(sa))
|
||||
int
|
||||
iso_pcbbind(isop, nam)
|
||||
register struct isopcb *isop;
|
||||
struct mbuf *nam;
|
||||
{
|
||||
register struct isopcb *head = isop->isop_head;
|
||||
register struct sockaddr_iso *siso;
|
||||
struct iso_ifaddr *ia;
|
||||
union {
|
||||
char data[2];
|
||||
u_short s;
|
||||
} suf;
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam);
|
||||
ENDDEBUG
|
||||
suf.s = 0;
|
||||
if (iso_ifaddr == 0) /* any interfaces attached? */
|
||||
return EADDRNOTAVAIL;
|
||||
if (isop->isop_laddr) /* already bound */
|
||||
return EADDRINUSE;
|
||||
if(nam == (struct mbuf *)0) {
|
||||
isop->isop_laddr = &isop->isop_sladdr;
|
||||
isop->isop_sladdr.siso_len = sizeof(struct sockaddr_iso);
|
||||
isop->isop_sladdr.siso_family = AF_ISO;
|
||||
isop->isop_sladdr.siso_tlen = 2;
|
||||
isop->isop_sladdr.siso_nlen = 0;
|
||||
isop->isop_sladdr.siso_slen = 0;
|
||||
isop->isop_sladdr.siso_plen = 0;
|
||||
goto noname;
|
||||
}
|
||||
siso = mtod(nam, struct sockaddr_iso *);
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbbind(name len 0x%x)\n", nam->m_len);
|
||||
printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr));
|
||||
ENDDEBUG
|
||||
/*
|
||||
* We would like sort of length check but since some OSI addrs
|
||||
* do not have fixed length, we can't really do much.
|
||||
* The ONLY thing we can say is that an osi addr has to have
|
||||
* at LEAST an afi and one more byte and had better fit into
|
||||
* a struct iso_addr.
|
||||
* However, in fact the size of the whole thing is a struct
|
||||
* sockaddr_iso, so probably this is what we should check for.
|
||||
*/
|
||||
if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) {
|
||||
return ENAMETOOLONG;
|
||||
}
|
||||
if (siso->siso_nlen) {
|
||||
/* non-zero net addr- better match one of our interfaces */
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbbind: bind to NOT zeroisoaddr\n");
|
||||
ENDDEBUG
|
||||
for (ia = iso_ifaddr; ia; ia = ia->ia_next)
|
||||
if (SAME_ISOADDR(siso, &ia->ia_addr))
|
||||
break;
|
||||
if (ia == 0)
|
||||
return EADDRNOTAVAIL;
|
||||
}
|
||||
if (siso->siso_len <= sizeof (isop->isop_sladdr)) {
|
||||
isop->isop_laddr = &isop->isop_sladdr;
|
||||
} else {
|
||||
if ((nam = m_copy(nam, 0, (int)M_COPYALL)) == 0)
|
||||
return ENOBUFS;
|
||||
isop->isop_laddr = mtod(nam, struct sockaddr_iso *);
|
||||
}
|
||||
bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len);
|
||||
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;
|
||||
} else {
|
||||
register char *cp;
|
||||
noname:
|
||||
cp = TSEL(isop->isop_laddr);
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbbind noname\n");
|
||||
ENDDEBUG
|
||||
do {
|
||||
if (head->isop_lport++ < ISO_PORT_RESERVED ||
|
||||
head->isop_lport > ISO_PORT_USERRESERVED)
|
||||
head->isop_lport = ISO_PORT_RESERVED;
|
||||
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));
|
||||
}
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbbind returns 0, suf 0x%x\n", suf);
|
||||
ENDDEBUG
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* FUNCTION: iso_pcbconnect
|
||||
*
|
||||
* PURPOSE: Make the isopcb (isop) look like it's connected.
|
||||
* In other words, give it the peer address given in
|
||||
* the mbuf * (nam). Make sure such a combination
|
||||
* of local, peer addresses doesn't already exist
|
||||
* for this protocol. Internet mentality prevails here,
|
||||
* wherein a src,dst pair uniquely identifies a connection.
|
||||
* Both net address and port must be specified in argument
|
||||
* (nam).
|
||||
* If we don't have a local address for this socket yet,
|
||||
* we pick one by calling iso_pcbbind().
|
||||
*
|
||||
* RETURNS: errno E* or 0 if ok.
|
||||
*
|
||||
* SIDE EFFECTS: Looks up a route, which may cause one to be left
|
||||
* in the isopcb.
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
int
|
||||
iso_pcbconnect(isop, nam)
|
||||
register struct isopcb *isop;
|
||||
struct mbuf *nam;
|
||||
{
|
||||
register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *);
|
||||
int local_zero, error = 0;
|
||||
struct iso_ifaddr *ia;
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x",
|
||||
isop, isop->isop_socket, nam);
|
||||
printf("nam->m_len 0x%x), addr:\n", nam->m_len);
|
||||
dump_isoaddr(siso);
|
||||
ENDDEBUG
|
||||
if (nam->m_len < siso->siso_len)
|
||||
return EINVAL;
|
||||
if (siso->siso_family != AF_ISO)
|
||||
return EAFNOSUPPORT;
|
||||
if (siso->siso_nlen == 0) {
|
||||
if (ia = iso_ifaddr) {
|
||||
int nlen = ia->ia_addr.siso_nlen;
|
||||
ovbcopy(TSEL(siso), nlen + TSEL(siso),
|
||||
siso->siso_plen + siso->siso_tlen + siso->siso_slen);
|
||||
bcopy((caddr_t)&ia->ia_addr.siso_addr,
|
||||
(caddr_t)&siso->siso_addr, nlen + 1);
|
||||
/* includes siso->siso_nlen = nlen; */
|
||||
} else
|
||||
return EADDRNOTAVAIL;
|
||||
}
|
||||
/*
|
||||
* Local zero means either not bound, or bound to a TSEL, but no
|
||||
* particular local interface. So, if we want to send somebody
|
||||
* we need to choose a return address.
|
||||
*/
|
||||
local_zero =
|
||||
((isop->isop_laddr == 0) || (isop->isop_laddr->siso_nlen == 0));
|
||||
if (local_zero) {
|
||||
int flags;
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbconnect localzero 1\n");
|
||||
ENDDEBUG
|
||||
/*
|
||||
* If route is known or can be allocated now,
|
||||
* our src addr is taken from the i/f, else punt.
|
||||
*/
|
||||
flags = isop->isop_socket->so_options & SO_DONTROUTE;
|
||||
if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags,
|
||||
(struct sockaddr **)0, &ia))
|
||||
return error;
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x",
|
||||
isop->isop_route.ro_rt);
|
||||
printf(" ia 0x%x\n", ia);
|
||||
ENDDEBUG
|
||||
}
|
||||
IFDEBUG(D_ISO)
|
||||
printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n",
|
||||
isop, isop->isop_socket);
|
||||
ENDDEBUG
|
||||
if (local_zero) {
|
||||
int nlen, tlen, totlen; caddr_t oldtsel, newtsel;
|
||||
siso = isop->isop_laddr;
|
||||
if (siso == 0 || siso->siso_tlen == 0)
|
||||
(void)iso_pcbbind(isop, (struct mbuf *)0);
|
||||
/*
|
||||
* Here we have problem of squezeing in a definite network address
|
||||
* into an existing sockaddr_iso, which in fact may not have room
|
||||
* for it. This gets messy.
|
||||
*/
|
||||
siso = isop->isop_laddr;
|
||||
oldtsel = TSEL(siso);
|
||||
tlen = siso->siso_tlen;
|
||||
nlen = ia->ia_addr.siso_nlen;
|
||||
totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]);
|
||||
if ((siso == &isop->isop_sladdr) &&
|
||||
(totlen > sizeof(isop->isop_sladdr))) {
|
||||
struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT);
|
||||
if (m == 0)
|
||||
return ENOBUFS;
|
||||
m->m_len = totlen;
|
||||
isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *);
|
||||
}
|
||||
siso->siso_nlen = ia->ia_addr.siso_nlen;
|
||||
newtsel = TSEL(siso);
|
||||
ovbcopy(oldtsel, newtsel, tlen);
|
||||
bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen);
|
||||
siso->siso_tlen = tlen;
|
||||
siso->siso_family = AF_ISO;
|
||||
siso->siso_len = totlen;
|
||||
siso = mtod(nam, struct sockaddr_iso *);
|
||||
}
|
||||
IFDEBUG(D_ISO)
|
||||
printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n",
|
||||
isop, isop->isop_socket);
|
||||
ENDDEBUG
|
||||
/*
|
||||
* If we had to allocate space to a previous big foreign address,
|
||||
* and for some reason we didn't free it, we reuse it knowing
|
||||
* that is going to be big enough, as sockaddrs are delivered in
|
||||
* 128 byte mbufs.
|
||||
* If the foreign address is small enough, we use default space;
|
||||
* otherwise, we grab an mbuf to copy into.
|
||||
*/
|
||||
if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) {
|
||||
if (siso->siso_len <= sizeof(isop->isop_sfaddr))
|
||||
isop->isop_faddr = &isop->isop_sfaddr;
|
||||
else {
|
||||
struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT);
|
||||
if (m == 0)
|
||||
return ENOBUFS;
|
||||
isop->isop_faddr = mtod(m, struct sockaddr_iso *);
|
||||
}
|
||||
}
|
||||
bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len);
|
||||
IFDEBUG(D_ISO)
|
||||
printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n",
|
||||
isop, isop->isop_socket);
|
||||
printf("iso_pcbconnect connected to addr:\n");
|
||||
dump_isoaddr(isop->isop_faddr);
|
||||
printf("iso_pcbconnect end: src addr:\n");
|
||||
dump_isoaddr(isop->isop_laddr);
|
||||
ENDDEBUG
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_pcbdisconnect()
|
||||
*
|
||||
* PURPOSE: washes away the peer address info so the socket
|
||||
* appears to be disconnected.
|
||||
* If there's no file descriptor associated with the socket
|
||||
* it detaches the pcb.
|
||||
*
|
||||
* RETURNS: Nada.
|
||||
*
|
||||
* SIDE EFFECTS: May detach the pcb.
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
void
|
||||
iso_pcbdisconnect(isop)
|
||||
struct isopcb *isop;
|
||||
{
|
||||
void iso_pcbdetach();
|
||||
register struct sockaddr_iso *siso;
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbdisconnect(isop 0x%x)\n", isop);
|
||||
ENDDEBUG
|
||||
/*
|
||||
* Preserver binding infnormation if already bound.
|
||||
*/
|
||||
if ((siso = isop->isop_laddr) && siso->siso_nlen && siso->siso_tlen) {
|
||||
caddr_t otsel = TSEL(siso);
|
||||
siso->siso_nlen = 0;
|
||||
ovbcopy(otsel, TSEL(siso), siso->siso_tlen);
|
||||
}
|
||||
if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr)
|
||||
m_freem(dtom(isop->isop_faddr));
|
||||
isop->isop_faddr = 0;
|
||||
if (isop->isop_socket->so_state & SS_NOFDREF)
|
||||
iso_pcbdetach(isop);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_pcbdetach
|
||||
*
|
||||
* PURPOSE: detach the pcb at *(isop) from it's socket and free
|
||||
* the mbufs associated with the pcb..
|
||||
* Dequeues (isop) from its head.
|
||||
*
|
||||
* RETURNS: Nada.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
void
|
||||
iso_pcbdetach(isop)
|
||||
struct isopcb *isop;
|
||||
{
|
||||
struct socket *so = isop->isop_socket;
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n",
|
||||
isop, isop->isop_socket, so);
|
||||
ENDDEBUG
|
||||
#ifdef TPCONS
|
||||
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) {
|
||||
lcp->lcd_upper = 0;
|
||||
lcp->lcd_upnext = 0;
|
||||
pk_disconnect(lcp);
|
||||
}
|
||||
isop->isop_chan = 0;
|
||||
}
|
||||
#endif
|
||||
if (so) { /* in the x.25 domain, we sometimes have no socket */
|
||||
so->so_pcb = 0;
|
||||
sofree(so);
|
||||
}
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbdetach 2 \n");
|
||||
ENDDEBUG
|
||||
if (isop->isop_options)
|
||||
(void)m_free(isop->isop_options);
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbdetach 3 \n");
|
||||
ENDDEBUG
|
||||
if (isop->isop_route.ro_rt)
|
||||
rtfree(isop->isop_route.ro_rt);
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbdetach 3.1\n");
|
||||
ENDDEBUG
|
||||
if (isop->isop_clnpcache != NULL) {
|
||||
struct clnp_cache *clcp =
|
||||
mtod(isop->isop_clnpcache, struct clnp_cache *);
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n",
|
||||
clcp, clcp->clc_hdr);
|
||||
ENDDEBUG
|
||||
if (clcp->clc_hdr != NULL)
|
||||
m_free(clcp->clc_hdr);
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbdetach 3.3: freeing cache x%x\n",
|
||||
isop->isop_clnpcache);
|
||||
ENDDEBUG
|
||||
m_free(isop->isop_clnpcache);
|
||||
}
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbdetach 4 \n");
|
||||
ENDDEBUG
|
||||
remque(isop);
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbdetach 5 \n");
|
||||
ENDDEBUG
|
||||
if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr))
|
||||
m_freem(dtom(isop->isop_laddr));
|
||||
free((caddr_t)isop, M_PCB);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_pcbnotify
|
||||
*
|
||||
* PURPOSE: notify all connections in this protocol's queue (head)
|
||||
* that have peer address (dst) of the problem (errno)
|
||||
* by calling (notify) on the connections' isopcbs.
|
||||
*
|
||||
* RETURNS: Rien.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: (notify) is called at splimp!
|
||||
*/
|
||||
void
|
||||
iso_pcbnotify(head, siso, errno, notify)
|
||||
struct isopcb *head;
|
||||
register struct sockaddr_iso *siso;
|
||||
int errno, (*notify)();
|
||||
{
|
||||
register struct isopcb *isop;
|
||||
int s = splimp();
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify);
|
||||
ENDDEBUG
|
||||
for (isop = head->isop_next; isop != head; isop = isop->isop_next) {
|
||||
if (isop->isop_socket == 0 || isop->isop_faddr == 0 ||
|
||||
!SAME_ISOADDR(siso, isop->isop_faddr)) {
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" ,
|
||||
isop, isop->isop_socket);
|
||||
printf("addrmatch cmp'd with (0x%x):\n", isop->isop_faddr);
|
||||
dump_isoaddr(isop->isop_faddr);
|
||||
ENDDEBUG
|
||||
continue;
|
||||
}
|
||||
if (errno)
|
||||
isop->isop_socket->so_error = errno;
|
||||
if (notify)
|
||||
(*notify)(isop);
|
||||
}
|
||||
splx(s);
|
||||
IFDEBUG(D_ISO)
|
||||
printf("END OF iso_pcbnotify\n" );
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: iso_pcblookup
|
||||
*
|
||||
* PURPOSE: looks for a given combination of (faddr), (fport),
|
||||
* (lport), (laddr) in the queue named by (head).
|
||||
* Argument (flags) is ignored.
|
||||
*
|
||||
* RETURNS: ptr to the isopcb if it finds a connection matching
|
||||
* these arguments, o.w. returns zero.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
struct isopcb *
|
||||
iso_pcblookup(head, fportlen, fport, laddr)
|
||||
struct isopcb *head;
|
||||
register struct sockaddr_iso *laddr;
|
||||
caddr_t fport;
|
||||
int fportlen;
|
||||
{
|
||||
register struct isopcb *isop;
|
||||
register caddr_t lp = TSEL(laddr);
|
||||
unsigned int llen = laddr->siso_tlen;
|
||||
|
||||
IFDEBUG(D_ISO)
|
||||
printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n",
|
||||
head, laddr, fport);
|
||||
ENDDEBUG
|
||||
for (isop = head->isop_next; isop != head; isop = isop->isop_next) {
|
||||
if (isop->isop_laddr == 0 || isop->isop_laddr == laddr)
|
||||
continue;
|
||||
if (isop->isop_laddr->siso_tlen != llen)
|
||||
continue;
|
||||
if (bcmp(lp, TSEL(isop->isop_laddr), llen))
|
||||
continue;
|
||||
if (fportlen && isop->isop_faddr &&
|
||||
bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen))
|
||||
continue;
|
||||
/* PHASE2
|
||||
* addrmatch1 should be iso_addrmatch(a, b, mask)
|
||||
* where mask is taken from isop->isop_laddrmask (new field)
|
||||
* isop_lnetmask will also be available in isop
|
||||
if (laddr != &zeroiso_addr &&
|
||||
!iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr)))
|
||||
continue;
|
||||
*/
|
||||
if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr)))
|
||||
continue;
|
||||
return (isop);
|
||||
}
|
||||
return (struct isopcb *)0;
|
||||
}
|
||||
#endif /* ISO */
|
||||
@@ -1,119 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)iso_pcb.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: iso_pcb.h,v 1.3 1994/08/21 06:14:20 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_ISO_PCB_H_
|
||||
#define _NETISO_ISO_PCB_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/iso_pcb.h,v 1.3 1994/08/21 06:14:20 paul Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/iso_pcb.h,v $ */
|
||||
|
||||
#define MAXX25CRUDLEN 16 /* 16 bytes of call request user data */
|
||||
|
||||
/*
|
||||
* Common structure pcb for argo protocol implementation.
|
||||
*/
|
||||
struct isopcb {
|
||||
struct isopcb *isop_next,*isop_prev; /* pointers to other pcb's */
|
||||
struct isopcb *isop_head; /* pointer back to chain of pcbs for
|
||||
this protocol */
|
||||
struct socket *isop_socket; /* back pointer to socket */
|
||||
struct sockaddr_iso *isop_laddr;
|
||||
struct sockaddr_iso *isop_faddr;
|
||||
struct route_iso {
|
||||
struct rtentry *ro_rt;
|
||||
struct sockaddr_iso ro_dst;
|
||||
} isop_route; /* CLNP routing entry */
|
||||
struct mbuf *isop_options; /* CLNP options */
|
||||
struct mbuf *isop_optindex; /* CLNP options index */
|
||||
struct mbuf *isop_clnpcache; /* CLNP cached hdr */
|
||||
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 */
|
||||
struct sockaddr_iso isop_sladdr, /* preallocated laddr */
|
||||
isop_sfaddr; /* preallocated faddr */
|
||||
};
|
||||
|
||||
#ifdef sotorawcb
|
||||
/*
|
||||
* Common structure pcb for raw clnp protocol access.
|
||||
* Here are clnp specific extensions to the raw control block,
|
||||
* and space is allocated to the necessary sockaddrs.
|
||||
*/
|
||||
struct rawisopcb {
|
||||
struct rawcb risop_rcb; /* common control block prefix */
|
||||
int risop_flags; /* flags, e.g. raw sockopts */
|
||||
struct isopcb risop_isop; /* space for bound addresses, routes etc.*/
|
||||
};
|
||||
#endif
|
||||
|
||||
#define sotoisopcb(so) ((struct isopcb *)(so)->so_pcb)
|
||||
#define sotorawisopcb(so) ((struct rawisopcb *)(so)->so_pcb)
|
||||
|
||||
#ifdef KERNEL
|
||||
struct isopcb *iso_pcblookup();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,201 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)iso_proto.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: iso_proto.c,v 1.3 1995/05/11 00:13:20 wollman Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/iso_proto.c,v 1.3 1995/05/11 00:13:20 wollman Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/iso_proto.c,v $
|
||||
*
|
||||
* 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/param.h>
|
||||
#include <sys/kernel.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 tp_ctloutput(), tpclnp_ctlinput(), tpclnp_input(), tp_usrreq();
|
||||
int tp_init(), tp_fasttimo(), tp_slowtimo(), tp_drain();
|
||||
int cons_init(), tpcons_input();
|
||||
|
||||
int isis_input();
|
||||
int esis_input(), esis_ctlinput(), esis_init(), esis_usrreq();
|
||||
int idrp_input(), idrp_init(), idrp_usrreq();
|
||||
int cltp_input(), cltp_ctlinput(), cltp_init(), cltp_usrreq(), cltp_output();
|
||||
|
||||
#ifdef TUBA
|
||||
int tuba_usrreq(), tuba_ctloutput(), tuba_init(), tuba_tcpinput();
|
||||
int tuba_slowtimo(), tuba_fasttimo();
|
||||
#endif
|
||||
|
||||
struct protosw isosw[] = {
|
||||
/*
|
||||
* We need a datagram entry through which net mgmt programs can get
|
||||
* to the iso_control procedure (iso ioctls). Thus, a minimal
|
||||
* SOCK_DGRAM interface is provided here.
|
||||
* THIS ONE MUST BE FIRST: Kludge city : socket() says if(!proto) call
|
||||
* pffindtype, which gets the first entry that matches the type.
|
||||
* sigh.
|
||||
*/
|
||||
{ SOCK_DGRAM, &isodomain, ISOPROTO_CLTP, PR_ATOMIC|PR_ADDR,
|
||||
0, cltp_output, 0, 0,
|
||||
cltp_usrreq,
|
||||
cltp_init, 0, 0, 0
|
||||
},
|
||||
|
||||
/*
|
||||
* A datagram interface for clnp cannot co-exist with TP/CLNP
|
||||
* because CLNP has no way to discriminate incoming TP packets from
|
||||
* packets coming in for any other higher layer protocol.
|
||||
* Old way: set it up so that pffindproto(... dgm, clnp) fails.
|
||||
* New way: let pffindproto work (for x.25, thank you) but create
|
||||
* a clnp_usrreq() that returns error on PRU_ATTACH.
|
||||
*/
|
||||
{SOCK_DGRAM, &isodomain, ISOPROTO_CLNP, 0,
|
||||
0, clnp_output, 0, 0,
|
||||
clnp_usrreq,
|
||||
clnp_init, 0, clnp_slowtimo, clnp_drain,
|
||||
},
|
||||
|
||||
/* raw clnp */
|
||||
{ SOCK_RAW, &isodomain, ISOPROTO_RAW, PR_ATOMIC|PR_ADDR,
|
||||
rclnp_input, rclnp_output, 0, rclnp_ctloutput,
|
||||
clnp_usrreq,
|
||||
0, 0, 0, 0
|
||||
},
|
||||
|
||||
/* ES-IS protocol */
|
||||
{ SOCK_DGRAM, &isodomain, ISOPROTO_ESIS, PR_ATOMIC|PR_ADDR,
|
||||
esis_input, 0, esis_ctlinput, 0,
|
||||
esis_usrreq,
|
||||
esis_init, 0, 0, 0
|
||||
},
|
||||
|
||||
/* ISOPROTO_INTRAISIS */
|
||||
{ SOCK_DGRAM, &isodomain, ISOPROTO_INTRAISIS, PR_ATOMIC|PR_ADDR,
|
||||
isis_input, 0, 0, 0,
|
||||
esis_usrreq,
|
||||
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,
|
||||
tp_usrreq,
|
||||
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,
|
||||
tpcons_input, 0, 0, tp_ctloutput,
|
||||
tp_usrreq,
|
||||
cons_init, 0, 0, 0,
|
||||
},
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct domain isodomain = {
|
||||
AF_ISO, /* family */
|
||||
"iso-domain", /* name */
|
||||
0, /* initialize routine */
|
||||
0, /* externalize access rights */
|
||||
0, /* dispose of internalized rights */
|
||||
isosw, /* protosw */
|
||||
&isosw[sizeof(isosw)/sizeof(isosw[0])], /* NPROTOSW */
|
||||
0, /* next */
|
||||
rn_inithead, /* rtattach */
|
||||
48, /* rtoffset */
|
||||
sizeof(struct sockaddr_iso) /* maxkeylen */
|
||||
};
|
||||
|
||||
DOMAIN_SET(iso);
|
||||
#endif /* ISO */
|
||||
@@ -1,739 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)iso_snpac.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: iso_snpac.c,v 1.4 1995/05/30 08:10:58 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/iso_snpac.c,v 1.4 1995/05/30 08:10:58 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/iso_snpac.c,v $ */
|
||||
|
||||
#ifdef ISO
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/iso_snpac.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/clnp_stat.h>
|
||||
#include <netiso/esis.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
|
||||
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();
|
||||
|
||||
struct sockaddr_iso blank_siso = {sizeof(blank_siso), AF_ISO};
|
||||
extern u_long iso_hashchar();
|
||||
static struct sockaddr_iso
|
||||
dst = {sizeof(dst), AF_ISO},
|
||||
gte = {sizeof(dst), AF_ISO},
|
||||
src = {sizeof(dst), AF_ISO},
|
||||
msk = {sizeof(dst), AF_ISO},
|
||||
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; \
|
||||
Bcopy(r, &a.siso_addr, 1 + (r)->isoa_len);}
|
||||
#define S(x) ((struct sockaddr *)&(x))
|
||||
|
||||
static struct sockaddr_dl blank_dl = {sizeof(blank_dl), AF_LINK};
|
||||
static struct sockaddr_dl gte_dl;
|
||||
#define zap_linkaddr(a, b, c, i) \
|
||||
(*a = blank_dl, bcopy(b, a->sdl_data, a->sdl_alen = c), a->sdl_index = i)
|
||||
|
||||
/*
|
||||
* We only keep track of a single IS at a time.
|
||||
*/
|
||||
struct rtentry *known_is;
|
||||
|
||||
/*
|
||||
* Addresses taken from NBS agreements, December 1987.
|
||||
*
|
||||
* These addresses assume on-the-wire transmission of least significant
|
||||
* bit first. This is the method used by 802.3. When these
|
||||
* addresses are passed to the token ring driver, (802.5), they
|
||||
* must be bit-swaped because 802.5 transmission order is MSb first.
|
||||
*
|
||||
* Furthermore, according to IBM Austin, these addresses are not
|
||||
* true token ring multicast addresses. More work is necessary
|
||||
* to get multicast to work right on token ring.
|
||||
*
|
||||
* Currently, the token ring driver does not handle multicast, so
|
||||
* these addresses are converted into the broadcast address in
|
||||
* lan_output() That means that if these multicast addresses change
|
||||
* the token ring driver must be altered.
|
||||
*/
|
||||
char all_es_snpa[] = { 0x09, 0x00, 0x2b, 0x00, 0x00, 0x04 };
|
||||
char all_is_snpa[] = { 0x09, 0x00, 0x2b, 0x00, 0x00, 0x05 };
|
||||
char all_l1is_snpa[] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x14};
|
||||
char all_l2is_snpa[] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x15};
|
||||
|
||||
union sockunion {
|
||||
struct sockaddr_iso siso;
|
||||
struct sockaddr_dl sdl;
|
||||
struct sockaddr sa;
|
||||
};
|
||||
|
||||
/*
|
||||
* FUNCTION: llc_rtrequest
|
||||
*
|
||||
* PURPOSE: Manage routing table entries specific to LLC for ISO.
|
||||
*
|
||||
* NOTES: This does a lot of obscure magic;
|
||||
*/
|
||||
llc_rtrequest(req, rt, sa)
|
||||
int req;
|
||||
register struct rtentry *rt;
|
||||
struct sockaddr *sa;
|
||||
{
|
||||
register union sockunion *gate = (union sockunion *)rt->rt_gateway;
|
||||
register struct llinfo_llc *lc = (struct llinfo_llc *)rt->rt_llinfo, *lc2;
|
||||
struct rtentry *rt2;
|
||||
struct ifnet *ifp = rt->rt_ifp;
|
||||
int addrlen = ifp->if_addrlen;
|
||||
#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)
|
||||
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) {
|
||||
iso_setmcasts(ifp, req);
|
||||
rt_setgate(rt, rt_key(rt), &blank_dl);
|
||||
return;
|
||||
}
|
||||
if (lc != 0)
|
||||
return; /* happens on a route change */
|
||||
/* FALLTHROUGH */
|
||||
case RTM_RESOLVE:
|
||||
/*
|
||||
* Case 2: This route may come from cloning, or a manual route
|
||||
* add with a LL address.
|
||||
*/
|
||||
if (gate->sdl.sdl_family != AF_LINK) {
|
||||
log(LOG_DEBUG, "llc_rtrequest: got non-link non-gateway route\n");
|
||||
break;
|
||||
}
|
||||
R_Malloc(lc, struct llinfo_llc *, sizeof (*lc));
|
||||
rt->rt_llinfo = (caddr_t)lc;
|
||||
if (lc == 0) {
|
||||
log(LOG_DEBUG, "llc_rtrequest: malloc failed\n");
|
||||
break;
|
||||
}
|
||||
Bzero(lc, sizeof(*lc));
|
||||
lc->lc_rt = rt;
|
||||
rt->rt_flags |= RTF_LLINFO;
|
||||
insque(lc, &llinfo_llc);
|
||||
if (gate->sdl.sdl_alen == sizeof(struct esis_req) + addrlen) {
|
||||
gate->sdl.sdl_alen -= sizeof(struct esis_req);
|
||||
bcopy(addrlen + LLADDR(&gate->sdl),
|
||||
(caddr_t)&lc->lc_er, sizeof(lc->lc_er));
|
||||
} else if (gate->sdl.sdl_alen == addrlen)
|
||||
lc->lc_flags = (SNPA_ES | SNPA_VALID | SNPA_PERM);
|
||||
break;
|
||||
case RTM_DELETE:
|
||||
if (rt->rt_flags & RTF_CLONING)
|
||||
iso_setmcasts(ifp, req);
|
||||
if (lc == 0)
|
||||
return;
|
||||
remque(lc);
|
||||
Free(lc);
|
||||
rt->rt_llinfo = 0;
|
||||
rt->rt_flags &= ~RTF_LLINFO;
|
||||
break;
|
||||
}
|
||||
if (rt->rt_rmx.rmx_mtu == 0) {
|
||||
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 0
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* FUNCTION: iso_snparesolve
|
||||
*
|
||||
* PURPOSE: Resolve an iso address into snpa address
|
||||
*
|
||||
* RETURNS: 0 if addr is resolved
|
||||
* errno if addr is unknown
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: Now that we have folded the snpa cache into the routing
|
||||
* table, we know there is no snpa address known for this
|
||||
* destination. If we know of a default IS, then the address
|
||||
* of the IS is returned. If no IS is known, then return the
|
||||
* multi-cast address for "all ES" for this interface.
|
||||
*
|
||||
* NB: the last case described above constitutes the
|
||||
* query configuration function 9542, sec 6.5
|
||||
* A mechanism is needed to prevent this function from
|
||||
* being invoked if the system is an IS.
|
||||
*/
|
||||
iso_snparesolve(ifp, dest, snpa, snpa_len)
|
||||
struct ifnet *ifp; /* outgoing interface */
|
||||
struct sockaddr_iso *dest; /* destination */
|
||||
caddr_t snpa; /* RESULT: snpa to be used */
|
||||
int *snpa_len; /* RESULT: length of snpa */
|
||||
{
|
||||
struct llinfo_llc *sc; /* ptr to snpa table entry */
|
||||
caddr_t found_snpa;
|
||||
int addrlen;
|
||||
|
||||
/*
|
||||
* This hack allows us to send esis packets that have the destination snpa
|
||||
* addresss embedded in the destination nsap address
|
||||
*/
|
||||
if (dest->siso_data[0] == AFI_SNA) {
|
||||
/*
|
||||
* This is a subnetwork address. Return it immediately
|
||||
*/
|
||||
IFDEBUG(D_SNPA)
|
||||
printf("iso_snparesolve: return SN address\n");
|
||||
ENDDEBUG
|
||||
addrlen = dest->siso_nlen - 1; /* subtract size of AFI */
|
||||
found_snpa = (caddr_t) dest->siso_data + 1;
|
||||
/*
|
||||
* If we are an IS, we can't do much with the packet;
|
||||
* Check if we know about an IS.
|
||||
*/
|
||||
} else if (iso_systype != SNPA_IS && known_is != 0 &&
|
||||
(sc = (struct llinfo_llc *)known_is->rt_llinfo) &&
|
||||
(sc->lc_flags & SNPA_VALID)) {
|
||||
register struct sockaddr_dl *sdl =
|
||||
(struct sockaddr_dl *)(known_is->rt_gateway);
|
||||
found_snpa = LLADDR(sdl);
|
||||
addrlen = sdl->sdl_alen;
|
||||
} else if (ifp->if_flags & IFF_BROADCAST) {
|
||||
/*
|
||||
* no IS, no match. Return "all es" multicast address for this
|
||||
* interface, as per Query Configuration Function (9542 sec 6.5)
|
||||
*
|
||||
* Note: there is a potential problem here. If the destination
|
||||
* is on the subnet and it does not respond with a ESH, but
|
||||
* does send back a TP CC, a connection could be established
|
||||
* where we always transmit the CLNP packet to "all es"
|
||||
*/
|
||||
addrlen = ifp->if_addrlen;
|
||||
found_snpa = (caddr_t)all_es_snpa;
|
||||
} else
|
||||
return (ENETUNREACH);
|
||||
bcopy(found_snpa, snpa, *snpa_len = addrlen);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: snpac_free
|
||||
*
|
||||
* PURPOSE: free an entry in the iso address map table
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: If there is a route entry associated with cache
|
||||
* entry, then delete that as well
|
||||
*/
|
||||
snpac_free(lc)
|
||||
register struct llinfo_llc *lc; /* entry to free */
|
||||
{
|
||||
register struct rtentry *rt = lc->lc_rt;
|
||||
register struct iso_addr *r;
|
||||
|
||||
if (known_is == rt)
|
||||
known_is = 0;
|
||||
if (rt && (rt->rt_flags & RTF_UP) &&
|
||||
(rt->rt_flags & (RTF_DYNAMIC | RTF_MODIFIED))) {
|
||||
RTFREE(rt);
|
||||
rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt),
|
||||
rt->rt_flags, (struct rtentry **)0);
|
||||
RTFREE(rt);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: snpac_add
|
||||
*
|
||||
* PURPOSE: Add an entry to the snpa cache
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: If entry already exists, then update holding time.
|
||||
*/
|
||||
snpac_add(ifp, nsap, snpa, type, ht, nsellength)
|
||||
struct ifnet *ifp; /* interface info is related to */
|
||||
struct iso_addr *nsap; /* nsap to add */
|
||||
caddr_t snpa; /* translation */
|
||||
char type; /* SNPA_IS or SNPA_ES */
|
||||
u_short ht; /* holding time (in seconds) */
|
||||
int nsellength; /* nsaps may differ only in trailing bytes */
|
||||
{
|
||||
register struct llinfo_llc *lc;
|
||||
register struct rtentry *rt;
|
||||
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, iftype = ifp->if_type;
|
||||
|
||||
IFDEBUG(D_SNPA)
|
||||
printf("snpac_add(%x, %x, %x, %x, %x, %x)\n",
|
||||
ifp, nsap, snpa, type, ht, nsellength);
|
||||
ENDDEBUG
|
||||
zap_isoaddr(dst, nsap);
|
||||
rt = rtalloc1(S(dst), 0, 0UL);
|
||||
IFDEBUG(D_SNPA)
|
||||
printf("snpac_add: rtalloc1 returns %x\n", rt);
|
||||
ENDDEBUG
|
||||
if (rt == 0) {
|
||||
struct sockaddr *netmask;
|
||||
int flags;
|
||||
add:
|
||||
if (nsellength) {
|
||||
netmask = S(msk); flags = RTF_UP;
|
||||
snpac_fixdstandmask(nsellength);
|
||||
} else {
|
||||
netmask = 0; flags = RTF_UP | RTF_HOST;
|
||||
}
|
||||
new_entry = 1;
|
||||
zap_linkaddr((>e_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);
|
||||
rt = mrt;
|
||||
rt->rt_refcnt--;
|
||||
} else {
|
||||
register struct sockaddr_dl *sdl = (struct sockaddr_dl *)rt->rt_gateway;
|
||||
rt->rt_refcnt--;
|
||||
if ((rt->rt_flags & RTF_LLINFO) == 0)
|
||||
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);
|
||||
rt = 0;
|
||||
goto add;
|
||||
} else {
|
||||
static struct iso_addr nsap2; register char *cp;
|
||||
nsap2 = *nsap;
|
||||
cp = nsap2.isoa_genaddr + nsap->isoa_len - nsellength;
|
||||
while (cp < (char *)(1 + &nsap2))
|
||||
*cp++ = 0;
|
||||
(void) snpac_add(ifp, &nsap2, snpa, type, ht, nsellength);
|
||||
}
|
||||
}
|
||||
if (sdl->sdl_family != AF_LINK || sdl->sdl_alen == 0) {
|
||||
int old_sdl_len = sdl->sdl_len;
|
||||
if (old_sdl_len < sizeof(*sdl)) {
|
||||
log(LOG_DEBUG, "snpac_add: cant make room for lladdr\n");
|
||||
return (0);
|
||||
}
|
||||
zap_linkaddr(sdl, snpa, snpalen, index);
|
||||
sdl->sdl_len = old_sdl_len;
|
||||
sdl->sdl_type = iftype;
|
||||
new_entry = 1;
|
||||
}
|
||||
}
|
||||
if ((lc = (struct llinfo_llc *)rt->rt_llinfo) == 0)
|
||||
panic("snpac_rtrequest");
|
||||
rt->rt_rmx.rmx_expire = ht + time.tv_sec;
|
||||
lc->lc_flags = SNPA_VALID | type;
|
||||
if ((type & SNPA_IS) && !(iso_systype & SNPA_IS))
|
||||
snpac_logdefis(rt);
|
||||
return (new_entry);
|
||||
}
|
||||
|
||||
static void
|
||||
snpac_fixdstandmask(nsellength)
|
||||
{
|
||||
register char *cp = msk.siso_data, *cplim;
|
||||
|
||||
cplim = cp + (dst.siso_nlen -= nsellength);
|
||||
msk.siso_len = cplim - (char *)&msk;
|
||||
msk.siso_nlen = 0;
|
||||
while (cp < cplim)
|
||||
*cp++ = -1;
|
||||
while (cp < (char *)msk.siso_pad)
|
||||
*cp++ = 0;
|
||||
for (cp = dst.siso_data + dst.siso_nlen; cp < (char *)dst.siso_pad; )
|
||||
*cp++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: snpac_ioctl
|
||||
*
|
||||
* PURPOSE: Set/Get the system type and esis parameters
|
||||
*
|
||||
* RETURNS: 0 on success, or unix error code
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
snpac_ioctl (so, cmd, data)
|
||||
struct socket *so;
|
||||
int cmd; /* ioctl to process */
|
||||
caddr_t data; /* data for the cmd */
|
||||
{
|
||||
register struct systype_req *rq = (struct systype_req *)data;
|
||||
|
||||
IFDEBUG(D_IOCTL)
|
||||
if (cmd == SIOCSSTYPE)
|
||||
printf("snpac_ioctl: cmd set, type x%x, ht %d, ct %d\n",
|
||||
rq->sr_type, rq->sr_holdt, rq->sr_configt);
|
||||
else
|
||||
printf("snpac_ioctl: cmd get\n");
|
||||
ENDDEBUG
|
||||
|
||||
if (cmd == SIOCSSTYPE) {
|
||||
if ((so->so_state & SS_PRIV) == 0)
|
||||
return (EPERM);
|
||||
if ((rq->sr_type & (SNPA_ES|SNPA_IS)) == (SNPA_ES|SNPA_IS))
|
||||
return(EINVAL);
|
||||
if (rq->sr_type & SNPA_ES) {
|
||||
iso_systype = SNPA_ES;
|
||||
} else if (rq->sr_type & SNPA_IS) {
|
||||
iso_systype = SNPA_IS;
|
||||
} else {
|
||||
return(EINVAL);
|
||||
}
|
||||
esis_holding_time = rq->sr_holdt;
|
||||
esis_config_time = rq->sr_configt;
|
||||
if (esis_esconfig_time != rq->sr_esconfigt) {
|
||||
untimeout(esis_config, (caddr_t)0);
|
||||
esis_esconfig_time = rq->sr_esconfigt;
|
||||
esis_config();
|
||||
}
|
||||
} else if (cmd == SIOCGSTYPE) {
|
||||
rq->sr_type = iso_systype;
|
||||
rq->sr_holdt = esis_holding_time;
|
||||
rq->sr_configt = esis_config_time;
|
||||
rq->sr_esconfigt = esis_esconfig_time;
|
||||
} else {
|
||||
return (EINVAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: snpac_logdefis
|
||||
*
|
||||
* PURPOSE: Mark the IS passed as the default IS
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
snpac_logdefis(sc)
|
||||
register struct rtentry *sc;
|
||||
{
|
||||
register struct iso_addr *r;
|
||||
register struct sockaddr_dl *sdl = (struct sockaddr_dl *)sc->rt_gateway;
|
||||
register struct rtentry *rt;
|
||||
|
||||
if (known_is == sc || !(sc->rt_flags & RTF_HOST))
|
||||
return;
|
||||
if (known_is) {
|
||||
RTFREE(known_is);
|
||||
}
|
||||
known_is = sc;
|
||||
sc->rt_refcnt++;
|
||||
rt = rtalloc1((struct sockaddr *)&zsi, 0, 0UL);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: snpac_age
|
||||
*
|
||||
* PURPOSE: Time out snpac entries
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: When encountering an entry for the first time, snpac_age
|
||||
* may delete up to SNPAC_AGE too many seconds. Ie.
|
||||
* if the entry is added a moment before snpac_age is
|
||||
* called, the entry will immediately have SNPAC_AGE
|
||||
* seconds taken off the holding time, even though
|
||||
* it has only been held a brief moment.
|
||||
*
|
||||
* The proper way to do this is set an expiry timeval
|
||||
* equal to current time + holding time. Then snpac_age
|
||||
* would time out entries where expiry date is older
|
||||
* than the current time.
|
||||
*/
|
||||
void
|
||||
snpac_age()
|
||||
{
|
||||
register struct llinfo_llc *lc, *nlc;
|
||||
register struct rtentry *rt;
|
||||
|
||||
timeout(snpac_age, (caddr_t)0, SNPAC_AGE * hz);
|
||||
|
||||
for (lc = llinfo_llc.lc_next; lc != & llinfo_llc; lc = nlc) {
|
||||
nlc = lc->lc_next;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: snpac_ownmulti
|
||||
*
|
||||
* PURPOSE: Determine if the snpa address is a multicast address
|
||||
* of the same type as the system.
|
||||
*
|
||||
* RETURNS: true or false
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: Used by interface drivers when not in eavesdrop mode
|
||||
* as interm kludge until
|
||||
* real multicast addresses can be configured
|
||||
*/
|
||||
snpac_ownmulti(snpa, len)
|
||||
caddr_t snpa;
|
||||
u_int len;
|
||||
{
|
||||
return (((iso_systype & SNPA_ES) &&
|
||||
(!bcmp(snpa, (caddr_t)all_es_snpa, len))) ||
|
||||
((iso_systype & SNPA_IS) &&
|
||||
(!bcmp(snpa, (caddr_t)all_is_snpa, len))));
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: snpac_flushifp
|
||||
*
|
||||
* PURPOSE: Flush entries associated with specific ifp
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
snpac_flushifp(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
register struct llinfo_llc *lc;
|
||||
|
||||
for (lc = llinfo_llc.lc_next; lc != & llinfo_llc; lc = lc->lc_next) {
|
||||
if (lc->lc_rt->rt_ifp == ifp && (lc->lc_flags & SNPA_VALID))
|
||||
snpac_free(lc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: snpac_rtrequest
|
||||
*
|
||||
* PURPOSE: Make a routing request
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: In the future, this should make a request of a user
|
||||
* level routing daemon.
|
||||
*/
|
||||
snpac_rtrequest(req, host, gateway, netmask, flags, ret_nrt)
|
||||
int req;
|
||||
struct iso_addr *host;
|
||||
struct iso_addr *gateway;
|
||||
struct iso_addr *netmask;
|
||||
short flags;
|
||||
struct rtentry **ret_nrt;
|
||||
{
|
||||
register struct iso_addr *r;
|
||||
|
||||
IFDEBUG(D_SNPA)
|
||||
printf("snpac_rtrequest: ");
|
||||
if (req == RTM_ADD)
|
||||
printf("add");
|
||||
else if (req == RTM_DELETE)
|
||||
printf("delete");
|
||||
else
|
||||
printf("unknown command");
|
||||
printf(" dst: %s\n", clnp_iso_addrp(host));
|
||||
printf("\tgateway: %s\n", clnp_iso_addrp(gateway));
|
||||
ENDDEBUG
|
||||
|
||||
|
||||
zap_isoaddr(dst, host);
|
||||
zap_isoaddr(gte, gateway);
|
||||
if (netmask) {
|
||||
zap_isoaddr(msk, netmask);
|
||||
msk.siso_nlen = 0;
|
||||
msk.siso_len = msk.siso_pad - (u_char *)&msk;
|
||||
}
|
||||
|
||||
rtrequest(req, S(dst), S(gte), (netmask ? S(msk) : (struct sockaddr *)0),
|
||||
flags, ret_nrt);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: snpac_addrt
|
||||
*
|
||||
* PURPOSE: Associate a routing entry with an snpac entry
|
||||
*
|
||||
* RETURNS: nothing
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: If a cache entry exists for gateway, then
|
||||
* make a routing entry (host, gateway) and associate
|
||||
* with gateway.
|
||||
*
|
||||
* If a route already exists and is different, first delete
|
||||
* it.
|
||||
*
|
||||
* This could be made more efficient by checking
|
||||
* the existing route before adding a new one.
|
||||
*/
|
||||
snpac_addrt(ifp, host, gateway, netmask)
|
||||
struct ifnet *ifp;
|
||||
struct iso_addr *host, *gateway, *netmask;
|
||||
{
|
||||
register struct iso_addr *r;
|
||||
|
||||
zap_isoaddr(dst, host);
|
||||
zap_isoaddr(gte, gateway);
|
||||
if (netmask) {
|
||||
zap_isoaddr(msk, netmask);
|
||||
msk.siso_nlen = 0;
|
||||
msk.siso_len = msk.siso_pad - (u_char *)&msk;
|
||||
rtredirect(S(dst), S(gte), S(msk), RTF_DONE, S(gte), 0);
|
||||
} else
|
||||
rtredirect(S(dst), S(gte), (struct sockaddr *)0,
|
||||
RTF_DONE | RTF_HOST, S(gte), 0);
|
||||
}
|
||||
#endif /* ISO */
|
||||
@@ -1,120 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)iso_snpac.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: iso_snpac.h,v 1.4 1995/03/28 07:57:14 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_ISO_SNPAC_H_
|
||||
#define _NETISO_ISO_SNPAC_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
|
||||
#define MAX_SNPALEN 8 /* curiously equal to sizeof x.121 (
|
||||
plus 1 for nibble len) addr */
|
||||
struct snpa_req {
|
||||
struct iso_addr sr_isoa; /* nsap address */
|
||||
u_char sr_len; /* length of snpa */
|
||||
u_char sr_snpa[MAX_SNPALEN]; /* snpa associated
|
||||
with nsap address */
|
||||
u_char sr_flags; /* true if entry is valid */
|
||||
u_short sr_ht; /* holding time */
|
||||
};
|
||||
|
||||
#define SNPA_VALID 0x01
|
||||
#define SNPA_ES 0x02
|
||||
#define SNPA_IS 0x04
|
||||
#define SNPA_PERM 0x10
|
||||
|
||||
struct systype_req {
|
||||
short sr_holdt; /* holding timer */
|
||||
short sr_configt; /* configuration timer */
|
||||
short sr_esconfigt; /* suggested ES configuration timer */
|
||||
char sr_type; /* SNPA_ES or SNPA_IS */
|
||||
};
|
||||
|
||||
struct esis_req {
|
||||
short er_ht; /* holding time */
|
||||
u_char er_flags; /* type and validity */
|
||||
};
|
||||
/*
|
||||
* Space for this structure gets added onto the end of a route
|
||||
* going to an ethernet or other 802.[45x] device.
|
||||
*/
|
||||
|
||||
struct llinfo_llc {
|
||||
struct llinfo_llc *lc_next; /* keep all llc routes linked */
|
||||
struct llinfo_llc *lc_prev; /* keep all llc routes linked */
|
||||
struct rtentry *lc_rt; /* backpointer to route */
|
||||
struct esis_req lc_er; /* holding time, etc */
|
||||
#define lc_ht lc_er.er_ht
|
||||
#define lc_flags lc_er.er_flags
|
||||
};
|
||||
|
||||
|
||||
/* ISO arp IOCTL data structures */
|
||||
|
||||
#define SIOCSSTYPE _IOW('a', 39, struct systype_req) /* set system type */
|
||||
#define SIOCGSTYPE _IOR('a', 40, struct systype_req) /* get system type */
|
||||
|
||||
#ifdef KERNEL
|
||||
struct llinfo_llc llinfo_llc; /* head for linked lists */
|
||||
int iso_snparesolve __P((struct ifnet *ifp, struct sockaddr_iso *dest,
|
||||
caddr_t snpa, int *snpa_len));
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif
|
||||
@@ -1,146 +0,0 @@
|
||||
/*-
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* @(#)iso_var.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: iso_var.h,v 1.7 1995/12/10 13:45:20 phk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_ISO_VAR_H_
|
||||
#define _NETISO_ISO_VAR_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/* $Header: /home/ncvs/src/sys/netiso/iso_var.h,v 1.7 1995/12/10 13:45:20 phk Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/iso_var.h,v $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Interface address, iso version. One of these structures is
|
||||
* allocated for each interface with an osi address. The ifaddr
|
||||
* structure contains the protocol-independent part
|
||||
* of the structure, and is assumed to be first.
|
||||
*/
|
||||
struct iso_ifaddr {
|
||||
struct ifaddr ia_ifa; /* protocol-independent info */
|
||||
#define ia_ifp ia_ifa.ifa_ifp
|
||||
#define ia_flags ia_ifa.ifa_flags
|
||||
int ia_snpaoffset;
|
||||
struct iso_ifaddr *ia_next; /* next in list of iso addresses */
|
||||
struct sockaddr_iso ia_addr; /* reserve space for interface name */
|
||||
struct sockaddr_iso ia_dstaddr; /* reserve space for broadcast addr */
|
||||
#define ia_broadaddr ia_dstaddr
|
||||
struct sockaddr_iso ia_sockmask; /* reserve space for general netmask */
|
||||
};
|
||||
|
||||
struct iso_aliasreq {
|
||||
char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
struct sockaddr_iso ifra_addr;
|
||||
struct sockaddr_iso ifra_dstaddr;
|
||||
struct sockaddr_iso ifra_mask;
|
||||
int ifra_snpaoffset;
|
||||
};
|
||||
|
||||
struct iso_ifreq {
|
||||
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
struct sockaddr_iso ifr_Addr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Given a pointer to an iso_ifaddr (ifaddr),
|
||||
* return a pointer to the addr as a sockaddr_iso
|
||||
*/
|
||||
/*
|
||||
#define IA_SIS(ia) ((struct sockaddr_iso *)(ia.ia_ifa->ifa_addr))
|
||||
* works if sockaddr_iso becomes variable sized.
|
||||
*/
|
||||
#define IA_SIS(ia) (&(((struct iso_ifaddr *)ia)->ia_addr))
|
||||
|
||||
#define SIOCDIFADDR_ISO _IOW('i',25, struct iso_ifreq) /* delete IF addr */
|
||||
#define SIOCAIFADDR_ISO _IOW('i',26, struct iso_aliasreq)/* add/chg IFalias */
|
||||
#define SIOCGIFADDR_ISO _IOWR('i',33, struct iso_ifreq) /* get ifnet address */
|
||||
#define SIOCGIFDSTADDR_ISO _IOWR('i',34, struct iso_ifreq) /* get dst address */
|
||||
#define SIOCGIFNETMASK_ISO _IOWR('i',37, struct iso_ifreq) /* get dst address */
|
||||
|
||||
/*
|
||||
* This stuff should go in if.h or if_llc.h or someplace else,
|
||||
* but for now . . .
|
||||
*/
|
||||
|
||||
struct llc_etherhdr {
|
||||
char dst[6];
|
||||
char src[6];
|
||||
char len[2];
|
||||
char llc_dsap;
|
||||
char llc_ssap;
|
||||
char llc_ui_byte;
|
||||
};
|
||||
|
||||
struct snpa_hdr {
|
||||
struct ifnet *snh_ifp;
|
||||
char snh_dhost[6];
|
||||
char snh_shost[6];
|
||||
short snh_flags;
|
||||
};
|
||||
#ifdef KERNEL
|
||||
extern struct iso_ifaddr *iso_ifaddr;
|
||||
/* linked list of iso address ifaces */
|
||||
struct iso_ifaddr *iso_localifa __P((struct sockaddr_iso *siso));
|
||||
/* linked list of iso address ifaces */
|
||||
void clnlintr __P((void));
|
||||
struct ifqueue clnlintrq; /* clnl packet input queue */
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif
|
||||
-1342
File diff suppressed because it is too large
Load Diff
@@ -1,75 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_astring.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
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)",
|
||||
};
|
||||
@@ -1,94 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_clnp.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_clnp.h,v 1.3 1994/08/21 06:14:23 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_CLNP_H_
|
||||
#define _NETISO_TP_CLNP_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_clnp.h,v 1.3 1994/08/21 06:14:23 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_clnp.h,v $
|
||||
*
|
||||
* AF_ISO net-dependent structures and include files
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SOCK_STREAM
|
||||
#include <sys/socket.h>
|
||||
#endif /* SOCK_STREAM */
|
||||
|
||||
#ifndef RTFREE
|
||||
#include <net/route.h>
|
||||
#endif
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/clnp.h>
|
||||
#include <netiso/iso_pcb.h>
|
||||
#ifndef IF_DEQUEUE
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#include <netiso/iso_var.h>
|
||||
|
||||
struct isopcb tp_isopcb;
|
||||
/* queue of active inpcbs for tp ; for tp with dod ip */
|
||||
|
||||
#endif
|
||||
@@ -1,310 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_cons.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_cons.c,v 1.3 1994/11/15 14:26:15 bde Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_cons.c,v 1.3 1994/11/15 14:26:15 bde Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_cons.c,v $
|
||||
*
|
||||
* 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
|
||||
* through a switch table (struct nl_protosw *) tpcb->tp_nlproto
|
||||
* (see tp_pcb.c).
|
||||
* The routines here are:
|
||||
* tpcons_input: pullup and call tp_input w/ correct arguments
|
||||
* tpcons_output: package a pkt for cons given an isopcb & some data
|
||||
* cons_chan_to_tpcb: find a tpcb based on the channel #
|
||||
*/
|
||||
|
||||
#ifdef ISO
|
||||
#ifdef TPCONS
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/tp_param.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_pcb.h>
|
||||
#include <netiso/tp_trace.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_tpdu.h>
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_errno.h>
|
||||
#include <netiso/iso_pcb.h>
|
||||
#include <netiso/cons.h>
|
||||
#include <netiso/tp_seq.h>
|
||||
|
||||
#undef FALSE
|
||||
#undef TRUE
|
||||
#include <netccitt/x25.h>
|
||||
#include <netccitt/pk.h>
|
||||
#include <netccitt/pk_var.h>
|
||||
|
||||
#include <netiso/if_cons.c>
|
||||
int tpcons_output();
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_route_to() for PRU_CONNECT
|
||||
* FUNCTION, ARGUMENTS, SIDE EFFECTS and RETURN VALUE:
|
||||
* version of the previous procedure for X.25
|
||||
*/
|
||||
|
||||
tpcons_pcbconnect(isop, nam)
|
||||
struct isopcb *isop;
|
||||
register struct mbuf *nam;
|
||||
{
|
||||
int error;
|
||||
if (error = iso_pcbconnect(isop, nam))
|
||||
return error;
|
||||
if ((isop->isop_chan = (caddr_t) pk_attach((struct socket *)0)) == 0) {
|
||||
IFDEBUG(D_CCONS)
|
||||
printf("tpcons_pcbconnect: no pklcd; returns 0x%x\n", error);
|
||||
ENDDEBUG
|
||||
return ENOBUFS;
|
||||
}
|
||||
if (error = cons_connect(isop)) { /* if it doesn't work */
|
||||
/* oh, dear, throw packet away */
|
||||
pk_disconnect((struct pklcd *)isop->isop_chan);
|
||||
isop->isop_chan = 0;
|
||||
} else
|
||||
isop->isop_refcnt = 1;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* cons
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* THIS MAYBE BELONGS IN SOME OTHER PLACE??? but i think not -
|
||||
*/
|
||||
ProtoHook
|
||||
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 (tpcb) {
|
||||
struct tp_event E;
|
||||
int error = 0;
|
||||
|
||||
if (tpcb->tp_class == TP_CLASS_0) {
|
||||
/* only if class is exactly class zero, not
|
||||
* still in class negotiation
|
||||
*/
|
||||
/* fake an ack */
|
||||
register SeqNum seq = SEQ_ADD(tpcb, tpcb->tp_snduna, 1);
|
||||
|
||||
IFTRACE(D_DATA)
|
||||
tptrace(TPPTmisc, "FAKE ACK seq cdt 1",
|
||||
seq, 0,0,0);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_DATA)
|
||||
printf("FAKE ACK seq 0x%x cdt 1\n", seq );
|
||||
ENDDEBUG
|
||||
E.ATTR(AK_TPDU).e_cdt = 1;
|
||||
E.ATTR(AK_TPDU).e_seq = seq;
|
||||
E.ATTR(AK_TPDU).e_subseq = 0;
|
||||
E.ATTR(AK_TPDU).e_fcc_present = 0;
|
||||
error = DoEvent(AK_TPDU);
|
||||
if( error ) {
|
||||
tpcb->tp_sock->so_error = error;
|
||||
}
|
||||
} /* else ignore it */
|
||||
}
|
||||
break;
|
||||
case PRC_ROUTEDEAD:
|
||||
if (tpcb && tpcb->tp_class == TP_CLASS_0) {
|
||||
tpiso_reset(isop);
|
||||
break;
|
||||
} /* else drop through */
|
||||
default:
|
||||
(void) tpclnp_ctlinput(cmd, siso);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* cons's intr routine
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Take a packet (m) from cons, pullup m as required by tp,
|
||||
* ignore the socket argument, and call tp_input.
|
||||
* No return value.
|
||||
*/
|
||||
ProtoHook
|
||||
tpcons_input(m, faddr, laddr, channel)
|
||||
struct mbuf *m;
|
||||
struct sockaddr_iso *faddr, *laddr;
|
||||
caddr_t channel;
|
||||
{
|
||||
if( m == MNULL)
|
||||
return 0;
|
||||
|
||||
m = (struct mbuf *)tp_inputprep(m);
|
||||
|
||||
IFDEBUG(D_TPINPUT)
|
||||
printf("tpcons_input before tp_input(m 0x%x)\n", m);
|
||||
dump_buf( m, 12+ m->m_len);
|
||||
ENDDEBUG
|
||||
tp_input(m, faddr, laddr, channel, tpcons_output, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_emit()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Take a packet(m0) from tp and package it so that cons will accept it.
|
||||
* This means filling in a few of the fields.
|
||||
* inp 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.
|
||||
*/
|
||||
|
||||
int
|
||||
tpcons_output(isop, m0, datalen, nochksum)
|
||||
struct isopcb *isop;
|
||||
struct mbuf *m0;
|
||||
int datalen;
|
||||
int nochksum;
|
||||
{
|
||||
register struct mbuf *m = m0;
|
||||
int error;
|
||||
|
||||
IFDEBUG(D_EMIT)
|
||||
printf(
|
||||
"tpcons_output(isop 0x%x, m 0x%x, len 0x%x socket 0x%x\n",
|
||||
isop, m0, datalen, isop->isop_socket);
|
||||
ENDDEBUG
|
||||
if (m == MNULL)
|
||||
return 0;
|
||||
if ((m->m_flags & M_PKTHDR) == 0) {
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
if (m == 0)
|
||||
return ENOBUFS;
|
||||
m->m_next = m0;
|
||||
}
|
||||
m->m_pkthdr.len = datalen;
|
||||
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;
|
||||
}
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_error_emit()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Take a packet(m0) from tp and package it so that cons will accept it.
|
||||
* chan is the cons channel to use; datalen is the length of the data in the
|
||||
* mbuf string m0.
|
||||
* RETURN VALUE:
|
||||
* whatever (E*) is returned form the net layer output routine.
|
||||
*/
|
||||
|
||||
int
|
||||
tpcons_dg_output(chan, m0, datalen)
|
||||
caddr_t chan;
|
||||
struct mbuf *m0;
|
||||
int datalen;
|
||||
{
|
||||
return tpcons_output(((struct pklcd *)chan)->lcd_upnext, m0, datalen, 0);
|
||||
}
|
||||
#endif /* TPCONS */
|
||||
#endif /* ISO */
|
||||
@@ -1,997 +0,0 @@
|
||||
/*
|
||||
* $Id: tp_driver.c,v 1.2 1994/08/02 07:50:59 davidg Exp $
|
||||
*/
|
||||
#define _XEBEC_PG static
|
||||
|
||||
#include "tp_states.h"
|
||||
|
||||
static struct act_ent {
|
||||
int a_newstate;
|
||||
int a_action;
|
||||
} statetable[] = { {0,0},
|
||||
#include "tp_states.init"
|
||||
};
|
||||
|
||||
/* @(#)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);
|
||||
#define MCPY(d, w) (d ? m_copym(d, 0, (int)M_COPYALL, w): 0)
|
||||
|
||||
static trick_hc = 1;
|
||||
|
||||
int tp_emit(),
|
||||
tp_goodack(), tp_goodXack(),
|
||||
tp_stash()
|
||||
;
|
||||
void tp_indicate(), tp_getoptions(),
|
||||
tp_soisdisconnecting(), tp_soisdisconnected(),
|
||||
tp_recycle_tsuffix(),
|
||||
#ifdef TP_DEBUG_TIMERS
|
||||
tp_etimeout(), tp_euntimeout(),
|
||||
tp_ctimeout(), tp_cuntimeout(),
|
||||
tp_ctimeout_MIN(),
|
||||
#endif
|
||||
tp_freeref(), tp_detach(),
|
||||
tp0_stash(), tp0_send(),
|
||||
tp_netcmd(), tp_send()
|
||||
;
|
||||
|
||||
typedef struct tp_pcb tpcb_struct;
|
||||
|
||||
|
||||
|
||||
typedef tpcb_struct tp_PCB_;
|
||||
|
||||
#include "tp_events.h"
|
||||
|
||||
_XEBEC_PG int _Xebec_action(a,e,p)
|
||||
int a;
|
||||
struct tp_event *e;
|
||||
tp_PCB_ *p;
|
||||
{
|
||||
switch(a) {
|
||||
case -1: return tp_protocol_error(e,p);
|
||||
case 0x1:
|
||||
{
|
||||
(void) tp_emit(DC_TPDU_type, p, 0, 0, MNULL);
|
||||
}
|
||||
break;
|
||||
case 0x2:
|
||||
{
|
||||
# ifdef TP_DEBUG
|
||||
if( e->ev_number != AK_TPDU )
|
||||
printf("TPDU 0x%x in REFWAIT!!!!\n", e->ev_number);
|
||||
# endif TP_DEBUG
|
||||
}
|
||||
break;
|
||||
case 0x3:
|
||||
{
|
||||
/* oh, man is this grotesque or what? */
|
||||
(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);
|
||||
/* but it's necessary because this pseudo-ack may happen
|
||||
* before the CC arrives, but we HAVE to adjust the
|
||||
* snduna as a result of the ack, WHENEVER it arrives
|
||||
*/
|
||||
}
|
||||
break;
|
||||
case 0x4:
|
||||
{
|
||||
tp_detach(p);
|
||||
}
|
||||
break;
|
||||
case 0x5:
|
||||
{
|
||||
p->tp_refstate = REF_OPEN; /* has timers ??? */
|
||||
}
|
||||
break;
|
||||
case 0x6:
|
||||
{
|
||||
IFTRACE(D_CONN)
|
||||
tptrace(TPPTmisc, "CR datalen data", e->ev_union.EV_CR_TPDU.e_datalen, e->ev_union.EV_CR_TPDU.e_data,0,0);
|
||||
ENDTRACE
|
||||
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_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) {
|
||||
/* n/a for class 0 */
|
||||
ASSERT(p->tp_Xrcv.sb_cc == 0);
|
||||
sbappendrecord(&p->tp_Xrcv, e->ev_union.EV_CR_TPDU.e_data);
|
||||
e->ev_union.EV_CR_TPDU.e_data = MNULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x7:
|
||||
{
|
||||
IncStat(ts_tp0_conn);
|
||||
IFTRACE(D_CONN)
|
||||
tptrace(TPPTmisc, "Confiming", p, 0,0,0);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_CONN)
|
||||
printf("Confirming connection: p" );
|
||||
ENDDEBUG
|
||||
soisconnected(p->tp_sock);
|
||||
(void) tp_emit(CC_TPDU_type, p, 0,0, MNULL) ;
|
||||
p->tp_fcredit = 1;
|
||||
}
|
||||
break;
|
||||
case 0x8:
|
||||
{
|
||||
IncStat(ts_tp4_conn); /* even though not quite open */
|
||||
IFTRACE(D_CONN)
|
||||
tptrace(TPPTmisc, "Confiming", p, 0,0,0);
|
||||
ENDTRACE
|
||||
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_l_tpdusize;
|
||||
p->tp_retrans = p->tp_Nretrans;
|
||||
tp_ctimeout(p, TM_retrans, (int)p->tp_cc_ticks);
|
||||
}
|
||||
break;
|
||||
case 0x9:
|
||||
{
|
||||
IFDEBUG(D_CONN)
|
||||
printf("event: CR_TPDU emit CC failed done " );
|
||||
ENDDEBUG
|
||||
soisdisconnected(p->tp_sock);
|
||||
tp_recycle_tsuffix(p);
|
||||
tp_freeref(p->tp_lref);
|
||||
tp_detach(p);
|
||||
}
|
||||
break;
|
||||
case 0xa:
|
||||
{
|
||||
int error;
|
||||
struct mbuf *data = MNULL;
|
||||
|
||||
IFTRACE(D_CONN)
|
||||
tptrace(TPPTmisc, "T_CONN_req flags ucddata", (int)p->tp_flags,
|
||||
p->tp_ucddata, 0, 0);
|
||||
ENDTRACE
|
||||
data = MCPY(p->tp_ucddata, M_WAIT);
|
||||
if (data) {
|
||||
IFDEBUG(D_CONN)
|
||||
printf("T_CONN_req.trans m_copy cc 0x%x\n",
|
||||
p->tp_ucddata);
|
||||
dump_mbuf(data, "sosnd @ T_CONN_req");
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
if (error = tp_emit(CR_TPDU_type, p, 0, 0, data) )
|
||||
return error; /* driver WON'T change state; will return error */
|
||||
|
||||
p->tp_refstate = REF_OPEN; /* has timers */
|
||||
if(p->tp_class != TP_CLASS_0) {
|
||||
p->tp_retrans = p->tp_Nretrans;
|
||||
tp_ctimeout(p, TM_retrans, (int)p->tp_cr_ticks);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xb:
|
||||
{
|
||||
sbflush(&p->tp_Xrcv); /* purge non-delivered data data */
|
||||
if (e->ev_union.EV_DR_TPDU.e_datalen > 0) {
|
||||
sbappendrecord(&p->tp_Xrcv, e->ev_union.EV_DR_TPDU.e_data);
|
||||
e->ev_union.EV_DR_TPDU.e_data = MNULL;
|
||||
}
|
||||
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, 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, TM_retrans);
|
||||
if( e->ev_union.EV_DR_TPDU.e_sref != 0 )
|
||||
(void) tp_emit(DC_TPDU_type, p, 0, 0, MNULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
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, TM_reference); /* all */
|
||||
tp_etimeout(p, TM_reference, (int)p->tp_refer_ticks);
|
||||
}
|
||||
break;
|
||||
case 0xd:
|
||||
{
|
||||
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, TM_retrans);
|
||||
tp_soisdisconnected(p);
|
||||
}
|
||||
break;
|
||||
case 0xf:
|
||||
{
|
||||
tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason);
|
||||
tp_cuntimeout(p, TM_retrans);
|
||||
tp_soisdisconnected(p);
|
||||
}
|
||||
break;
|
||||
case 0x10:
|
||||
{
|
||||
tp_cuntimeout(p, TM_retrans);
|
||||
tp_soisdisconnected(p);
|
||||
}
|
||||
break;
|
||||
case 0x11:
|
||||
{ /* don't ask me why we have to do this - spec says so */
|
||||
(void) tp_emit(DR_TPDU_type, p, 0, E_TP_NO_SESSION, MNULL);
|
||||
/* don't bother with retransmissions of the DR */
|
||||
}
|
||||
break;
|
||||
case 0x12:
|
||||
{
|
||||
tp_soisdisconnecting(p->tp_sock);
|
||||
tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason);
|
||||
tp_soisdisconnected(p);
|
||||
tp_netcmd( p, CONN_CLOSE );
|
||||
}
|
||||
break;
|
||||
case 0x13:
|
||||
{
|
||||
if (p->tp_state == TP_OPEN) {
|
||||
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, 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, TM_retrans);
|
||||
IncStat(ts_tp0_conn);
|
||||
p->tp_fcredit = 1;
|
||||
soisconnected(p->tp_sock);
|
||||
}
|
||||
break;
|
||||
case 0x15:
|
||||
{
|
||||
IFDEBUG(D_CONN)
|
||||
printf("trans: CC_TPDU in CRSENT state flags 0x%x\n",
|
||||
(int)p->tp_flags);
|
||||
ENDDEBUG
|
||||
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;
|
||||
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_l_tpdusize;
|
||||
tp_getoptions(p);
|
||||
tp_cuntimeout(p, TM_retrans);
|
||||
if (p->tp_ucddata) {
|
||||
IFDEBUG(D_CONN)
|
||||
printf("dropping user connect data cc 0x%x\n",
|
||||
p->tp_ucddata->m_len);
|
||||
ENDDEBUG
|
||||
m_freem(p->tp_ucddata);
|
||||
p->tp_ucddata = 0;
|
||||
}
|
||||
soisconnected(p->tp_sock);
|
||||
if (e->ev_union.EV_CC_TPDU.e_datalen > 0) {
|
||||
ASSERT(p->tp_Xrcv.sb_cc == 0); /* should be empty */
|
||||
sbappendrecord(&p->tp_Xrcv, e->ev_union.EV_CC_TPDU.e_data);
|
||||
e->ev_union.EV_CC_TPDU.e_data = MNULL;
|
||||
}
|
||||
|
||||
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL);
|
||||
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
|
||||
}
|
||||
break;
|
||||
case 0x16:
|
||||
{
|
||||
struct mbuf *data = MNULL;
|
||||
int error;
|
||||
|
||||
IncStat(ts_retrans_cr);
|
||||
p->tp_cong_win = 1 * p->tp_l_tpdusize;
|
||||
data = MCPY(p->tp_ucddata, M_NOWAIT);
|
||||
if(p->tp_ucddata) {
|
||||
IFDEBUG(D_CONN)
|
||||
printf("TM_retrans.trans m_copy cc 0x%x\n", data);
|
||||
dump_mbuf(p->tp_ucddata, "sosnd @ TM_retrans");
|
||||
ENDDEBUG
|
||||
if( data == MNULL )
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
p->tp_retrans --;
|
||||
if( error = tp_emit(CR_TPDU_type, p, 0, 0, data) ) {
|
||||
p->tp_sock->so_error = error;
|
||||
}
|
||||
tp_ctimeout(p, TM_retrans, (int)p->tp_cr_ticks);
|
||||
}
|
||||
break;
|
||||
case 0x17:
|
||||
{
|
||||
IncStat(ts_conn_gaveup);
|
||||
p->tp_sock->so_error = ETIMEDOUT;
|
||||
tp_indicate(T_DISCONNECT, p, ETIMEDOUT);
|
||||
tp_soisdisconnected(p);
|
||||
}
|
||||
break;
|
||||
case 0x18:
|
||||
{
|
||||
int error;
|
||||
struct mbuf *data = MCPY(p->tp_ucddata, M_WAIT);
|
||||
|
||||
if( error = tp_emit(CC_TPDU_type, p, 0, 0, data) ) {
|
||||
p->tp_sock->so_error = error;
|
||||
}
|
||||
p->tp_retrans = p->tp_Nretrans;
|
||||
tp_ctimeout(p, TM_retrans, (int)p->tp_cc_ticks);
|
||||
}
|
||||
break;
|
||||
case 0x19:
|
||||
{
|
||||
int doack;
|
||||
|
||||
/*
|
||||
* Get rid of any confirm or connect data, so that if we
|
||||
* crash or close, it isn't thought of as disconnect data.
|
||||
*/
|
||||
if (p->tp_ucddata) {
|
||||
m_freem(p->tp_ucddata);
|
||||
p->tp_ucddata = 0;
|
||||
}
|
||||
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
|
||||
tp_cuntimeout(p, TM_retrans);
|
||||
soisconnected(p->tp_sock);
|
||||
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
|
||||
|
||||
/* see also next 2 transitions, if you make any changes */
|
||||
|
||||
doack = tp_stash(p, e);
|
||||
IFDEBUG(D_DATA)
|
||||
printf("tp_stash returns %d\n",doack);
|
||||
ENDDEBUG
|
||||
|
||||
if (doack) {
|
||||
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL );
|
||||
tp_ctimeout(p, TM_sendack, (int)p->tp_keepalive_ticks);
|
||||
} else
|
||||
tp_ctimeout( p, TM_sendack, (int)p->tp_sendack_ticks);
|
||||
|
||||
IFDEBUG(D_DATA)
|
||||
printf("after stash calling sbwakeup\n");
|
||||
ENDDEBUG
|
||||
}
|
||||
break;
|
||||
case 0x1a:
|
||||
{
|
||||
tp0_stash(p, e);
|
||||
sbwakeup( &p->tp_sock->so_rcv );
|
||||
|
||||
IFDEBUG(D_DATA)
|
||||
printf("after stash calling sbwakeup\n");
|
||||
ENDDEBUG
|
||||
}
|
||||
break;
|
||||
case 0x1b:
|
||||
{
|
||||
int doack; /* tells if we must ack immediately */
|
||||
|
||||
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
|
||||
sbwakeup( &p->tp_sock->so_rcv );
|
||||
|
||||
doack = tp_stash(p, e);
|
||||
IFDEBUG(D_DATA)
|
||||
printf("tp_stash returns %d\n",doack);
|
||||
ENDDEBUG
|
||||
|
||||
if(doack)
|
||||
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL );
|
||||
else
|
||||
tp_ctimeout_MIN( p, TM_sendack, (int)p->tp_sendack_ticks);
|
||||
|
||||
IFDEBUG(D_DATA)
|
||||
printf("after stash calling sbwakeup\n");
|
||||
ENDDEBUG
|
||||
}
|
||||
break;
|
||||
case 0x1c:
|
||||
{
|
||||
IFTRACE(D_DATA)
|
||||
tptrace(TPPTmisc, "NIW seq rcvnxt lcredit ",
|
||||
e->ev_union.EV_DT_TPDU.e_seq, p->tp_rcvnxt, p->tp_lcredit, 0);
|
||||
ENDTRACE
|
||||
IncStat(ts_dt_niw);
|
||||
m_freem(e->ev_union.EV_DT_TPDU.e_data);
|
||||
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
|
||||
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL );
|
||||
}
|
||||
break;
|
||||
case 0x1d:
|
||||
{
|
||||
if (p->tp_ucddata) {
|
||||
m_freem(p->tp_ucddata);
|
||||
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, TM_retrans);
|
||||
|
||||
soisconnected(p->tp_sock);
|
||||
IFTRACE(D_CONN)
|
||||
struct socket *so = p->tp_sock;
|
||||
tptrace(TPPTmisc,
|
||||
"called sosiconn: so so_state rcv.sb_sel rcv.sb_flags",
|
||||
so, so->so_state, so->so_rcv.sb_sel, so->so_rcv.sb_flags);
|
||||
tptrace(TPPTmisc,
|
||||
"called sosiconn 2: so_qlen so_error so_rcv.sb_cc so_head",
|
||||
so->so_qlen, so->so_error, so->so_rcv.sb_cc, so->so_head);
|
||||
ENDTRACE
|
||||
|
||||
tp_ctimeout(p, TM_sendack, (int)p->tp_keepalive_ticks);
|
||||
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
|
||||
}
|
||||
break;
|
||||
case 0x1e:
|
||||
{
|
||||
if( p->tp_state == TP_AKWAIT ) {
|
||||
if (p->tp_ucddata) {
|
||||
m_freem(p->tp_ucddata);
|
||||
p->tp_ucddata = 0;
|
||||
}
|
||||
tp_cuntimeout(p, TM_retrans);
|
||||
soisconnected(p->tp_sock);
|
||||
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",
|
||||
p->tp_Xrcvnxt,e->ev_union.EV_XPD_TPDU.e_seq, e->ev_union.EV_XPD_TPDU.e_datalen, e->ev_union.EV_XPD_TPDU.e_data->m_len);
|
||||
ENDTRACE
|
||||
|
||||
p->tp_sock->so_state |= SS_RCVATMARK;
|
||||
e->ev_union.EV_XPD_TPDU.e_data->m_flags |= M_EOR;
|
||||
sbinsertoob(&p->tp_Xrcv, e->ev_union.EV_XPD_TPDU.e_data);
|
||||
IFDEBUG(D_XPD)
|
||||
dump_mbuf(e->ev_union.EV_XPD_TPDU.e_data, "XPD TPDU: tp_Xrcv");
|
||||
ENDDEBUG
|
||||
tp_indicate(T_XDATA, p, 0);
|
||||
sbwakeup( &p->tp_Xrcv );
|
||||
|
||||
(void) tp_emit(XAK_TPDU_type, p, p->tp_Xrcvnxt, 0, MNULL);
|
||||
SEQ_INC(p, p->tp_Xrcvnxt);
|
||||
}
|
||||
break;
|
||||
case 0x1f:
|
||||
{
|
||||
if( p->tp_Xrcv.sb_cc == 0 ) {
|
||||
/* kludge for select(): */
|
||||
/* p->tp_sock->so_state &= ~SS_OOBAVAIL; */
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x20:
|
||||
{
|
||||
IFTRACE(D_XPD)
|
||||
tptrace(TPPTmisc, "XPD tpdu niw (Xrcvnxt, e_seq) or not cdt (cc)\n",
|
||||
p->tp_Xrcvnxt, e->ev_union.EV_XPD_TPDU.e_seq, p->tp_Xrcv.sb_cc , 0);
|
||||
ENDTRACE
|
||||
if( p->tp_Xrcvnxt != e->ev_union.EV_XPD_TPDU.e_seq )
|
||||
IncStat(ts_xpd_niw);
|
||||
if( p->tp_Xrcv.sb_cc ) {
|
||||
/* might as well kick 'em again */
|
||||
tp_indicate(T_XDATA, p, 0);
|
||||
IncStat(ts_xpd_dup);
|
||||
}
|
||||
m_freem(e->ev_union.EV_XPD_TPDU.e_data);
|
||||
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)
|
||||
*/
|
||||
}
|
||||
break;
|
||||
case 0x21:
|
||||
{
|
||||
struct socket *so = p->tp_sock;
|
||||
|
||||
/* detach from parent socket so it can finish closing */
|
||||
if (so->so_head) {
|
||||
if (!soqremque(so, 0) && !soqremque(so, 1))
|
||||
panic("tp: T_DETACH");
|
||||
so->so_head = 0;
|
||||
}
|
||||
tp_soisdisconnecting(p->tp_sock);
|
||||
tp_netcmd( p, CONN_CLOSE);
|
||||
tp_soisdisconnected(p);
|
||||
}
|
||||
break;
|
||||
case 0x22:
|
||||
{
|
||||
struct socket *so = p->tp_sock;
|
||||
struct mbuf *data = MNULL;
|
||||
|
||||
/* detach from parent socket so it can finish closing */
|
||||
if (so->so_head) {
|
||||
if (!soqremque(so, 0) && !soqremque(so, 1))
|
||||
panic("tp: T_DETACH");
|
||||
so->so_head = 0;
|
||||
}
|
||||
if (p->tp_state != TP_CLOSING) {
|
||||
tp_soisdisconnecting(p->tp_sock);
|
||||
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, TM_retrans, (int)p->tp_dr_ticks);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x23:
|
||||
{
|
||||
tp_soisdisconnecting(p->tp_sock);
|
||||
tp_netcmd( p, CONN_CLOSE);
|
||||
tp_soisdisconnected(p);
|
||||
}
|
||||
break;
|
||||
case 0x24:
|
||||
{
|
||||
struct mbuf *data = MCPY(p->tp_ucddata, M_WAIT);
|
||||
|
||||
if(p->tp_state == TP_OPEN) {
|
||||
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)
|
||||
printf("T_DISC_req.trans tp_ucddata 0x%x\n",
|
||||
p->tp_ucddata);
|
||||
dump_mbuf(data, "ucddata @ T_DISC_req");
|
||||
ENDDEBUG
|
||||
}
|
||||
tp_soisdisconnecting(p->tp_sock);
|
||||
p->tp_retrans = p->tp_Nretrans;
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case 0x25:
|
||||
{
|
||||
int error;
|
||||
struct mbuf *data = MCPY(p->tp_ucddata, M_WAIT);
|
||||
|
||||
IncStat(ts_retrans_cc);
|
||||
p->tp_retrans --;
|
||||
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, TM_retrans, (int)p->tp_cc_ticks);
|
||||
}
|
||||
break;
|
||||
case 0x26:
|
||||
{
|
||||
IncStat(ts_conn_gaveup);
|
||||
tp_soisdisconnecting(p->tp_sock);
|
||||
p->tp_sock->so_error = ETIMEDOUT;
|
||||
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, TM_retrans, (int)p->tp_dr_ticks);
|
||||
}
|
||||
break;
|
||||
case 0x27:
|
||||
{
|
||||
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);
|
||||
p->tp_sock->so_error = ETIMEDOUT;
|
||||
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, TM_retrans, (int)p->tp_dr_ticks);
|
||||
}
|
||||
break;
|
||||
case 0x28:
|
||||
{
|
||||
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);
|
||||
int shift;
|
||||
|
||||
IFTRACE(D_XPD)
|
||||
tptrace(TPPTmisc, "XPD retrans: Xuna Xsndnxt sndnxt snduna",
|
||||
p->tp_Xuna, p->tp_Xsndnxt, p->tp_sndnxt,
|
||||
p->tp_snduna);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_XPD)
|
||||
dump_mbuf(m, "XPD retrans emitting M");
|
||||
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, TM_retrans, ((int)p->tp_dt_ticks) << shift);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x29:
|
||||
{
|
||||
p->tp_rxtshift++;
|
||||
(void) tp_data_retrans(p);
|
||||
}
|
||||
break;
|
||||
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, TM_retrans, (int)p->tp_dr_ticks);
|
||||
}
|
||||
break;
|
||||
case 0x2b:
|
||||
{
|
||||
p->tp_sock->so_error = ETIMEDOUT;
|
||||
p->tp_refstate = REF_FROZEN;
|
||||
tp_recycle_tsuffix( p );
|
||||
tp_etimeout(p, TM_reference, (int)p->tp_refer_ticks);
|
||||
}
|
||||
break;
|
||||
case 0x2c:
|
||||
{
|
||||
tp_freeref(p->tp_lref);
|
||||
tp_detach(p);
|
||||
}
|
||||
break;
|
||||
case 0x2d:
|
||||
{
|
||||
if( p->tp_class != TP_CLASS_0) {
|
||||
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);
|
||||
}
|
||||
/* ignore it if class 0 - state tables are blank for this */
|
||||
}
|
||||
break;
|
||||
case 0x2e:
|
||||
{
|
||||
IFTRACE(D_DATA)
|
||||
tptrace(TPPTmisc, "T_DATA_req sndnxt snduna fcredit, tpcb",
|
||||
p->tp_sndnxt, p->tp_snduna, p->tp_fcredit, p);
|
||||
ENDTRACE
|
||||
|
||||
tp_send(p);
|
||||
}
|
||||
break;
|
||||
case 0x2f:
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* 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
|
||||
*/
|
||||
|
||||
IFTRACE(D_XPD)
|
||||
tptrace(TPPTmisc, "XPD req: Xuna Xsndnxt sndnxt snduna",
|
||||
p->tp_Xuna, p->tp_Xsndnxt, p->tp_sndnxt,
|
||||
p->tp_snduna);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_XPD)
|
||||
printf("T_XPD_req: sb_cc 0x%x\n", p->tp_Xsnd.sb_cc);
|
||||
dump_mbuf(m, "XPD req emitting M");
|
||||
ENDDEBUG
|
||||
error =
|
||||
tp_emit(XPD_TPDU_type, p, p->tp_Xuna, 1, m);
|
||||
p->tp_retrans = p->tp_Nretrans;
|
||||
|
||||
tp_ctimeout(p, TM_retrans, (int)p->tp_rxtcur);
|
||||
SEQ_INC(p, p->tp_Xsndnxt);
|
||||
}
|
||||
if(trick_hc)
|
||||
return error;
|
||||
}
|
||||
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, TM_inact, (int)p->tp_inact_ticks);
|
||||
}
|
||||
sbwakeup(sb);
|
||||
IFDEBUG(D_ACKRECV)
|
||||
printf("GOOD ACK new sndnxt 0x%x\n", p->tp_sndnxt);
|
||||
ENDDEBUG
|
||||
}
|
||||
break;
|
||||
case 0x31:
|
||||
{
|
||||
IFTRACE(D_ACKRECV)
|
||||
tptrace(TPPTmisc, "BOGUS ACK fcc_present, tp_r_subseq e_subseq",
|
||||
e->ev_union.EV_AK_TPDU.e_fcc_present, p->tp_r_subseq, e->ev_union.EV_AK_TPDU.e_subseq, 0);
|
||||
ENDTRACE
|
||||
if( p->tp_class != TP_CLASS_0 ) {
|
||||
|
||||
if ( !e->ev_union.EV_AK_TPDU.e_fcc_present ) {
|
||||
/* send ACK with FCC */
|
||||
IncStat( ts_ackreason[_ACK_FCC_] );
|
||||
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 1, MNULL);
|
||||
}
|
||||
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x32:
|
||||
{
|
||||
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
|
||||
tp_cuntimeout(p, TM_retrans);
|
||||
|
||||
sbwakeup( &p->tp_sock->so_snd );
|
||||
|
||||
/* resume normal data */
|
||||
tp_send(p);
|
||||
}
|
||||
break;
|
||||
case 0x33:
|
||||
{
|
||||
IFTRACE(D_ACKRECV)
|
||||
tptrace(TPPTmisc, "BOGUS XACK eventtype ", e->ev_number, 0, 0,0);
|
||||
ENDTRACE
|
||||
if( p->tp_class != TP_CLASS_0 ) {
|
||||
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:
|
||||
{
|
||||
if (sbspace(&p->tp_sock->so_rcv) > 0)
|
||||
tp0_openflow(p);
|
||||
}
|
||||
break;
|
||||
case 0x36:
|
||||
{
|
||||
if( trick_hc ) {
|
||||
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;
|
||||
case 0x37:
|
||||
{
|
||||
if(trick_hc)
|
||||
return ECONNABORTED;
|
||||
}
|
||||
break;
|
||||
case 0x38:
|
||||
{
|
||||
ASSERT( p->tp_state != TP_LISTENING );
|
||||
tp_indicate(T_DISCONNECT, p, ECONNRESET);
|
||||
tp_soisdisconnected(p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
_XEBEC_PG int
|
||||
_Xebec_index( e,p )
|
||||
struct tp_event *e;
|
||||
tp_PCB_ *p;
|
||||
{
|
||||
switch( (e->ev_number<<4)+(p->tp_state) ) {
|
||||
case 0x12:
|
||||
if ( p->tp_retrans > 0 ) return 0x1e;
|
||||
else return 0x1f;
|
||||
case 0x13:
|
||||
if ( p->tp_retrans > 0 ) return 0x2f;
|
||||
else return 0x30;
|
||||
case 0x14:
|
||||
if ( p->tp_retrans > 0 ) return 0x32;
|
||||
else return 0x31;
|
||||
case 0x15:
|
||||
if ( p->tp_retrans > 0 ) return 0x34;
|
||||
else return 0x35;
|
||||
case 0x54:
|
||||
if (p->tp_rxtshift < TP_NRETRANS) return 0x33;
|
||||
else return 0x31;
|
||||
case 0x64:
|
||||
if (p->tp_class == TP_CLASS_0) return 0x1a;
|
||||
else return 0x1b;
|
||||
case 0x77:
|
||||
if ( p->tp_class == TP_CLASS_0) return 0xd;
|
||||
else return 0xe;
|
||||
case 0x86:
|
||||
if ( e->ev_union.EV_DR_TPDU.e_sref != 0 ) return 0x2;
|
||||
else return 0x3;
|
||||
case 0xa2:
|
||||
if (p->tp_class == TP_CLASS_0) return 0x1c;
|
||||
else return 0x1d;
|
||||
case 0xb2:
|
||||
if (p->tp_class == TP_CLASS_0) return 0x5;
|
||||
else return 0x0;
|
||||
case 0xb4:
|
||||
if ( 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) ) return 0x3a;
|
||||
else return 0x3b;
|
||||
case 0xc3:
|
||||
if ( IN_RWINDOW( p, e->ev_union.EV_DT_TPDU.e_seq,
|
||||
p->tp_rcvnxt, SEQ(p, p->tp_rcvnxt + p->tp_lcredit)) ) return 0x21;
|
||||
else return 0x24;
|
||||
case 0xc4:
|
||||
if ( p->tp_class == TP_CLASS_0 ) return 0x22;
|
||||
else if ( IN_RWINDOW( p, e->ev_union.EV_DT_TPDU.e_seq,
|
||||
p->tp_rcvnxt, SEQ(p, p->tp_rcvnxt + p->tp_lcredit)) ) return 0x23;
|
||||
else return 0x25;
|
||||
case 0xd3:
|
||||
if (p->tp_Xrcvnxt == e->ev_union.EV_XPD_TPDU.e_seq) return 0x27;
|
||||
else return 0x2a;
|
||||
case 0xd4:
|
||||
if (p->tp_Xrcvnxt == e->ev_union.EV_XPD_TPDU.e_seq) return 0x27;
|
||||
else return 0x29;
|
||||
case 0xe4:
|
||||
if ( tp_goodXack(p, e->ev_union.EV_XAK_TPDU.e_seq) ) return 0x3c;
|
||||
else return 0x3d;
|
||||
case 0x102:
|
||||
if ( p->tp_class == TP_CLASS_0 ) return 0x2d;
|
||||
else return 0x2e;
|
||||
case 0x104:
|
||||
if ( p->tp_class == TP_CLASS_0 ) return 0x2d;
|
||||
else return 0x2e;
|
||||
case 0x144:
|
||||
if (p->tp_class == TP_CLASS_0) return 0x3f;
|
||||
else return 0x40;
|
||||
case 0x162:
|
||||
if (p->tp_class == TP_CLASS_0) return 0x2b;
|
||||
else return 0x2c;
|
||||
case 0x172:
|
||||
if ( p->tp_class != TP_CLASS_4 ) return 0x42;
|
||||
else return 0x46;
|
||||
case 0x174:
|
||||
if ( p->tp_class != TP_CLASS_4 ) return 0x42;
|
||||
else return 0x47;
|
||||
case 0x177:
|
||||
if ( p->tp_class != TP_CLASS_4 ) return 0x42;
|
||||
else return 0x43;
|
||||
case 0x188:
|
||||
if ( p->tp_class == TP_CLASS_0 ) return 0xf;
|
||||
else if (tp_emit(CC_TPDU_type, p, 0,0, MCPY(p->tp_ucddata, M_NOWAIT)) == 0) return 0x10;
|
||||
else return 0x11;
|
||||
default: return 0;
|
||||
} /* end switch */
|
||||
} /* _Xebec_index() */
|
||||
static int inx[26][9] = { {0,0,0,0,0,0,0,0,0,},
|
||||
{0x0,0x0,0x0,0x0,0x31,0x0,0x0,0x0,0x0, },
|
||||
{0x0,0x0,-1,-1,-1,-1,0x0,0x0,0x0, },
|
||||
{0x0,0x0,0x0,0x0,0x3e,0x0,0x0,0x0,0x0, },
|
||||
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, },
|
||||
{0x0,0x0,0x0,0x0,0x0,0x0,0x36,0x0,0x0, },
|
||||
{0x0,0x0,0x0,0x0,-1,0x0,0x0,0x0,0x0, },
|
||||
{0x0,0x7,0x15,0x1b,-1,0x17,0x3,0xa,0x0, },
|
||||
{0x0,0x19,0x6,0x20,0x37,0x8,0x3,-1,0x0, },
|
||||
{0x0,0x14,0x13,0x13,0x13,0x16,-1,0xa,0x0, },
|
||||
{0x0,0x7,0x6,0x1,0x9,0x18,0x3,0xa,0x0, },
|
||||
{0x0,0x19,-1,0x1,0x37,0x8,0x3,0xa,0x0, },
|
||||
{0x0,0x7,-1,0x26,-1,0x8,0x3,0xa,0x0, },
|
||||
{0x0,0x7,0x6,-1,-1,0x8,0x3,0xa,0x0, },
|
||||
{0x0,0x7,0x6,-1,-1,0x8,0x3,0xa,0x0, },
|
||||
{0x0,0x7,0x6,0x1,-1,0x8,0x3,0xa,0x0, },
|
||||
{0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x0,0x0, },
|
||||
{0x0,0x0,-1,0x2e,-1,0x0,0x4,0x0,0x2e, },
|
||||
{0x0,0xb,0x0,0x0,0x0,0x0,0x0,0x0,0x0, },
|
||||
{0x0,0x0,0x0,0x0,0x38,0x0,0x0,0x0,0x0, },
|
||||
{0x0,0x0,0x0,0x0,0x39,0x0,0x0,0x0,0x0, },
|
||||
{0x0,0x0,0x0,0x0,-1,0x0,0x41,0x0,0x0, },
|
||||
{0x0,0x0,0x0,0x0,0x28,0x0,0x41,0x0,0x0, },
|
||||
{0x0,0xc,-1,0x2c,0x0,0x2c,0x4,0xc,0x2c, },
|
||||
{0x0,0x49,-1,0x45,-1,0x44,0x48,-1,0x0, },
|
||||
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,-1, },
|
||||
};
|
||||
tp_driver(p, e)
|
||||
register tp_PCB_ *p;
|
||||
register struct tp_event *e;
|
||||
{
|
||||
register int index, error=0;
|
||||
struct act_ent *a;
|
||||
static struct act_ent erroraction = {0,-1};
|
||||
|
||||
index = inx[1 + e->ev_number][p->tp_state];
|
||||
if(index<0) index=_Xebec_index(e, p);
|
||||
if (index==0) {
|
||||
a = &erroraction;
|
||||
} else
|
||||
a = &statetable[index];
|
||||
|
||||
if(a->a_action)
|
||||
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;
|
||||
return error;
|
||||
}
|
||||
@@ -1,997 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_emit.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_emit.c,v 1.2 1994/08/02 07:51:02 davidg Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_emit.c,v 1.2 1994/08/02 07:51:02 davidg Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_emit.c,v $
|
||||
*
|
||||
* 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
|
||||
* necessary for headers, and set the fields as appropriate from
|
||||
* information found in the tpcb and net-level pcb.
|
||||
*
|
||||
* The worst thing about this code is adding the variable-length
|
||||
* options on a machine that requires alignment for any memory access
|
||||
* that isn't of size 1. See the macro ADDOPTION() below.
|
||||
*
|
||||
* We don't do any concatenation. (There's a kludge to test the
|
||||
* basic mechanism of separation under the 'w' tpdebug option, that's all.)
|
||||
*/
|
||||
|
||||
#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/time.h>
|
||||
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_pcb.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_timer.h>
|
||||
#include <netiso/tp_param.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_pcb.h>
|
||||
#include <netiso/tp_tpdu.h>
|
||||
#include <netiso/tp_trace.h>
|
||||
#include <netiso/tp_meas.h>
|
||||
#include <netiso/tp_seq.h>
|
||||
#include <netiso/iso_errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#ifdef TRUE
|
||||
#undef FALSE
|
||||
#undef TRUE
|
||||
#endif
|
||||
#include <netccitt/x25.h>
|
||||
#include <netccitt/pk.h>
|
||||
#include <netccitt/pk_var.h>
|
||||
|
||||
void iso_gen_csum();
|
||||
|
||||
|
||||
/* Here is a mighty kludge. The token ring misorders packets if you
|
||||
* fire them at it too fast, and TP sans checksum is "too fast", so
|
||||
* we have introduced a delay when checksumming isn't used.
|
||||
*/
|
||||
char tp_delay = 0x00; /* delay to keep token ring from blowing it */
|
||||
|
||||
/*
|
||||
* NAME: tp_emit()
|
||||
*
|
||||
* CALLED FROM: tp.trans and from tp_sbsend()
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Emits one tpdu of the type (dutype), of the format appropriate
|
||||
* to the connection described by the pcb (tpcb), with sequence
|
||||
* number (seq) (where appropriate), end-of-tsdu bit (eot) where
|
||||
* appropriate, and with the data in the mbuf chain (data).
|
||||
* For DR and ER tpdus, the argument (eot) is
|
||||
* the reason for issuing the tpdu rather than an end-of-tsdu indicator.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 OK
|
||||
* ENOBUFS
|
||||
* E* returned from net layer output rtn
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* WE ASSUME that the tp header + all options will fit in ONE mbuf.
|
||||
* If mbufs are 256 this will most likely be true, but if they are 128 it's
|
||||
* possible that they won't.
|
||||
* If you used every option on the CR + max. user data you'd overrun
|
||||
* 112 but unless you used > 115 bytes for the security
|
||||
* parameter, it would fit in a 256-byte mbuf (240 bytes for the header)
|
||||
* We don't support the security parameter, so this isn't a problem.
|
||||
* If security is added, we ought to remove this assumption.
|
||||
*
|
||||
* We do not implement the flow control confirmation "element of procedure".
|
||||
* A) it should not affect interoperability,
|
||||
* B) it should not be necessary - the protocol will eventually
|
||||
* straighten things out w/o FCC, as long as we don't have severely
|
||||
* mismatched keepalive and inactivity timers, and
|
||||
* C) it appears not to be REQUIRED, and
|
||||
* D) it's incredibly grotesque, and no doubt will lengthen a few
|
||||
* critical paths.
|
||||
* HOWEVER, we're thinking about putting it in anyway, for
|
||||
* completeness, just like we did with ack subsequencing.
|
||||
*/
|
||||
|
||||
int
|
||||
tp_emit(dutype, tpcb, seq, eot, data)
|
||||
int dutype;
|
||||
struct tp_pcb *tpcb;
|
||||
SeqNum seq;
|
||||
u_int eot;
|
||||
struct mbuf *data;
|
||||
{
|
||||
register struct tpdu *hdr;
|
||||
register struct mbuf *m;
|
||||
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
|
||||
* the end, at which time we subtract 1
|
||||
* THis is because if we subtract 1 right away, we end up adding
|
||||
* one every time we add an option.
|
||||
*/
|
||||
IFDEBUG(D_EMIT)
|
||||
printf(
|
||||
"tp_emit dutype 0x%x, tpcb 0x%x, eot 0x%x, seq 0x%x, data 0x%x",
|
||||
dutype, tpcb, eot, seq, data);
|
||||
ENDDEBUG
|
||||
|
||||
if (dutype == CR_TPDU || dutype == CC_TPDU) {
|
||||
m = (struct mbuf *) malloc((u_long)256, M_MBUF, M_DONTWAIT);
|
||||
if (m) {
|
||||
m->m_type = TPMT_TPHDR;
|
||||
mbstat.m_mtypes[TPMT_TPHDR]++;
|
||||
m->m_next = MNULL;
|
||||
m->m_nextpkt = MNULL;
|
||||
m->m_data = m->m_pktdat;
|
||||
m->m_flags = M_PKTHDR;
|
||||
}
|
||||
} else {
|
||||
MGETHDR(m, M_DONTWAIT, TPMT_TPHDR);
|
||||
}
|
||||
m->m_data += max_hdr;
|
||||
if (m == NULL) {
|
||||
if(data != (struct mbuf *)0)
|
||||
m_freem(data);
|
||||
error = ENOBUFS;
|
||||
goto done;
|
||||
}
|
||||
m->m_len = sizeof(struct tpdu);
|
||||
m->m_act = MNULL;
|
||||
|
||||
hdr = mtod(m, struct tpdu *);
|
||||
bzero((caddr_t)hdr, sizeof(struct tpdu));
|
||||
|
||||
{
|
||||
int tp_headersize();
|
||||
|
||||
hdr->tpdu_type = dutype;
|
||||
hdr->tpdu_li = tp_headersize(dutype, tpcb);
|
||||
/*
|
||||
* class 0 doesn't use this for DT
|
||||
* it'll just get overwritten below
|
||||
*/
|
||||
hdr->tpdu_dref = htons(tpcb->tp_fref);
|
||||
if( tpcb->tp_use_checksum ||
|
||||
(dutype == CR_TPDU_type && (tpcb->tp_class & TP_CLASS_4) )) {
|
||||
csum_offset = hdr->tpdu_li + 2; /* DOESN'T include csum */
|
||||
ADDOPTION(TPP_checksum, hdr, 2, eot /* dummy arg */);
|
||||
IFDEBUG(D_CHKSUM)
|
||||
printf(
|
||||
"tp_emit: csum_offset 0x%x, hdr->tpdu_li 0x%x\n",
|
||||
csum_offset, hdr->tpdu_li);
|
||||
ENDDEBUG
|
||||
}
|
||||
/*
|
||||
* VARIABLE PARTS...
|
||||
*/
|
||||
switch( dutype ) {
|
||||
|
||||
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);
|
||||
} else
|
||||
LOCAL_CREDIT(tpcb);
|
||||
|
||||
/* 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 ) {
|
||||
tpcb->tp_sent_uwe = tpcb->tp_lcredit -1;
|
||||
tpcb->tp_sent_rcvnxt = 1;
|
||||
tpcb->tp_sent_lcdt = tpcb->tp_lcredit;
|
||||
hdr->tpdu_cdt = tpcb->tp_lcredit;
|
||||
} else {
|
||||
#ifdef TPCONS
|
||||
if (tpcb->tp_netservice == ISO_CONS) {
|
||||
struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
|
||||
struct pklcd *lcp = (struct pklcd *)(isop->isop_chan);
|
||||
lcp->lcd_flags &= ~X25_DG_CIRCUIT;
|
||||
}
|
||||
#endif
|
||||
hdr->tpdu_cdt = 0;
|
||||
}
|
||||
hdr->tpdu_CCclass = tp_mask_to_num(tpcb->tp_class);
|
||||
hdr->tpdu_CCoptions =
|
||||
(tpcb->tp_xtd_format? TPO_XTD_FMT:0) |
|
||||
(tpcb->tp_use_efc? TPO_USE_EFC:0);
|
||||
|
||||
IFPERF(tpcb)
|
||||
u_char perf_meas = tpcb->tp_perf_on;
|
||||
ADDOPTION(TPP_perf_meas, hdr, sizeof(perf_meas), perf_meas);
|
||||
ENDPERF
|
||||
|
||||
if( dutype == CR_TPDU_type ) {
|
||||
IncStat(ts_CR_sent);
|
||||
|
||||
ASSERT( tpcb->tp_lsuffixlen > 0 );
|
||||
ASSERT( tpcb->tp_fsuffixlen > 0 );
|
||||
|
||||
ADDOPTION(TPP_calling_sufx, hdr,
|
||||
tpcb->tp_lsuffixlen, tpcb->tp_lsuffix[0]);
|
||||
ADDOPTION(TPP_called_sufx, hdr,
|
||||
tpcb->tp_fsuffixlen, tpcb->tp_fsuffix[0]);
|
||||
} else {
|
||||
IncStat(ts_CC_sent);
|
||||
}
|
||||
|
||||
ADDOPTION(TPP_tpdu_size, hdr,
|
||||
sizeof(tpcb->tp_tpdusize), tpcb->tp_tpdusize);
|
||||
|
||||
if (tpcb->tp_class != TP_CLASS_0) {
|
||||
short millisec = 500*(tpcb->tp_sendack_ticks);
|
||||
|
||||
millisec = htons(millisec);
|
||||
ADDOPTION(TPP_acktime, hdr, sizeof(short), millisec);
|
||||
|
||||
x = (tpcb->tp_use_nxpd? TPAO_USE_NXPD: 0)
|
||||
| (tpcb->tp_use_rcc? TPAO_USE_RCC : 0)
|
||||
| (tpcb->tp_use_checksum?0: TPAO_NO_CSUM)
|
||||
| (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)){
|
||||
|
||||
ASSERT( 1 == sizeof(tpcb->tp_vers) );
|
||||
ADDOPTION(TPP_vers, hdr, 1, tpcb->tp_vers);
|
||||
|
||||
/* for each alt protocol class x,
|
||||
* x = x<<4;
|
||||
* option = concat(option, x);
|
||||
* Well, for now we only have TP0 for an
|
||||
* alternative so... this is easy.
|
||||
*
|
||||
* HOWEVER... There should be NO alt protocol
|
||||
* class over CLNS. Need to see if the route suggests
|
||||
* CONS, and iff so add alt class.
|
||||
*/
|
||||
x = 0;
|
||||
ADDOPTION(TPP_alt_class, hdr, 1, x);
|
||||
}
|
||||
|
||||
if( hdr->tpdu_li > MLEN)
|
||||
panic("tp_emit CR/CC");
|
||||
}
|
||||
break;
|
||||
|
||||
case DR_TPDU_type:
|
||||
if( hdr->tpdu_DRdref == 0 ) {
|
||||
/* don't issue the DR */
|
||||
goto done;
|
||||
}
|
||||
hdr->tpdu_cdt = 0;
|
||||
hdr->tpdu_DRsref = htons(tpcb->tp_lref);
|
||||
hdr->tpdu_DRreason = (u_char)eot; /* WHICH BYTE OF THIS??? */
|
||||
|
||||
/* forget the add'l information variable part */
|
||||
IncStat(ts_DR_sent);
|
||||
break;
|
||||
|
||||
case DC_TPDU_type: /* not used in class 0 */
|
||||
ASSERT( tpcb->tp_class != TP_CLASS_0);
|
||||
hdr->tpdu_DCsref = htons(tpcb->tp_lref);
|
||||
hdr->tpdu_cdt = 0;
|
||||
data = (struct mbuf *)0;
|
||||
IncStat(ts_DC_sent);
|
||||
break;
|
||||
|
||||
case XAK_TPDU_type: /* xak not used in class 0 */
|
||||
ASSERT( tpcb->tp_class != TP_CLASS_0); /* fall through */
|
||||
hdr->tpdu_cdt = 0;
|
||||
|
||||
IFTRACE(D_XPD)
|
||||
tptraceTPCB(TPPTXack, seq, 0, 0, 0, 0);
|
||||
ENDTRACE
|
||||
data = (struct mbuf *)0;
|
||||
if (tpcb->tp_xtd_format) {
|
||||
#ifdef BYTE_ORDER
|
||||
union seq_type seqeotX;
|
||||
|
||||
seqeotX.s_seq = seq;
|
||||
seqeotX.s_eot = 1;
|
||||
hdr->tpdu_seqeotX = htonl(seqeotX.s_seqeot);
|
||||
#else
|
||||
hdr->tpdu_XAKseqX = seq;
|
||||
#endif /* BYTE_ORDER */
|
||||
} else {
|
||||
hdr->tpdu_XAKseq = seq;
|
||||
}
|
||||
IncStat(ts_XAK_sent);
|
||||
IncPStat(tpcb, tps_XAK_sent);
|
||||
break;
|
||||
|
||||
case XPD_TPDU_type: /* xpd not used in class 0 */
|
||||
ASSERT( tpcb->tp_class != TP_CLASS_0); /* fall through */
|
||||
hdr->tpdu_cdt = 0;
|
||||
if (tpcb->tp_xtd_format) {
|
||||
#ifdef BYTE_ORDER
|
||||
union seq_type seqeotX;
|
||||
|
||||
seqeotX.s_seq = seq;
|
||||
seqeotX.s_eot = 1;
|
||||
hdr->tpdu_seqeotX = htonl(seqeotX.s_seqeot);
|
||||
#else
|
||||
hdr->tpdu_XPDseqX = seq;
|
||||
hdr->tpdu_XPDeotX = 1; /* always 1 for XPD tpdu */
|
||||
#endif /* BYTE_ORDER */
|
||||
} else {
|
||||
hdr->tpdu_XPDseq = seq;
|
||||
hdr->tpdu_XPDeot = 1; /* always 1 for XPD tpdu */
|
||||
}
|
||||
IncStat(ts_XPD_sent);
|
||||
IncPStat(tpcb, tps_XPD_sent);
|
||||
|
||||
/* kludge to test the input size checking */
|
||||
IFDEBUG(D_SIZE_CHECK)
|
||||
/*if(data->m_len <= 16 && data->m_off < (MLEN-18) ) {
|
||||
printf("Sending too much data on XPD: 18 bytes\n");
|
||||
data->m_len = 18;
|
||||
}*/
|
||||
ENDDEBUG
|
||||
break;
|
||||
|
||||
case DT_TPDU_type:
|
||||
hdr->tpdu_cdt = 0;
|
||||
IFTRACE(D_DATA)
|
||||
tptraceTPCB(TPPTmisc, "emit DT: eot seq tpdu_li", eot, seq,
|
||||
hdr->tpdu_li, 0);
|
||||
ENDTRACE
|
||||
if (tpcb->tp_xtd_format) {
|
||||
#ifdef BYTE_ORDER
|
||||
union seq_type seqeotX;
|
||||
|
||||
seqeotX.s_seq = seq;
|
||||
seqeotX.s_eot = eot;
|
||||
hdr->tpdu_seqeotX = htonl(seqeotX.s_seqeot);
|
||||
#else
|
||||
hdr->tpdu_DTseqX = seq;
|
||||
hdr->tpdu_DTeotX = eot;
|
||||
#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);
|
||||
dump_buf( hdr, hdr->tpdu_li + 1 );
|
||||
ENDDEBUG
|
||||
((struct tp0du *)hdr)->tp0du_eot = eot;
|
||||
((struct tp0du *)hdr)->tp0du_mbz = 0;
|
||||
IFDEBUG(D_EMIT)
|
||||
printf("DT 2 tpdu: class 0 m 0x%x hdr 0x%x\n", m, hdr);
|
||||
dump_buf( hdr, hdr->tpdu_li + 1 );
|
||||
ENDDEBUG
|
||||
} else {
|
||||
hdr->tpdu_DTseq = seq;
|
||||
hdr->tpdu_DTeot = eot;
|
||||
}
|
||||
if(eot) {
|
||||
IncStat(ts_EOT_sent);
|
||||
}
|
||||
IncStat(ts_DT_sent);
|
||||
IncPStat(tpcb, tps_DT_sent);
|
||||
break;
|
||||
|
||||
case AK_TPDU_type:/* ak not used in class 0 */
|
||||
ASSERT( tpcb->tp_class != TP_CLASS_0);
|
||||
data = (struct mbuf *)0;
|
||||
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);
|
||||
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) ) {
|
||||
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);
|
||||
ENDTRACE
|
||||
if (tpcb->tp_xtd_format) {
|
||||
#ifdef BYTE_ORDER
|
||||
union seq_type seqeotX;
|
||||
|
||||
seqeotX.s_seq = seq;
|
||||
seqeotX.s_eot = 0;
|
||||
hdr->tpdu_seqeotX = htonl(seqeotX.s_seqeot);
|
||||
hdr->tpdu_AKcdtX = htons(tpcb->tp_lcredit);
|
||||
#else
|
||||
hdr->tpdu_cdt = 0;
|
||||
hdr->tpdu_AKseqX = seq;
|
||||
hdr->tpdu_AKcdtX = tpcb->tp_lcredit;
|
||||
#endif /* BYTE_ORDER */
|
||||
} else {
|
||||
hdr->tpdu_AKseq = seq;
|
||||
hdr->tpdu_AKcdt = tpcb->tp_lcredit;
|
||||
}
|
||||
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)
|
||||
*/
|
||||
IFDEBUG(D_RENEG)
|
||||
printf("Adding subseq 0x%x\n", tpcb->tp_s_subseq);
|
||||
ENDDEBUG
|
||||
tpcb->tp_s_subseq++;
|
||||
/*
|
||||
* add tmp subseq and do a htons on it.
|
||||
*/
|
||||
ADDOPTION(TPP_subseq, hdr,
|
||||
sizeof(tpcb->tp_s_subseq), tpcb->tp_s_subseq);
|
||||
} else
|
||||
tpcb->tp_s_subseq = 0;
|
||||
|
||||
if ( tpcb->tp_sendfcc || eot ) /* overloaded to mean SEND FCC */ {
|
||||
/*
|
||||
* Rules for sending FCC ("should" send when) :
|
||||
* %a) received an ack from peer with NO NEWS whatsoever,
|
||||
* and it did not contain an FCC
|
||||
* b) received an ack from peer that opens its closed window.
|
||||
* c) received an ack from peer after it reneged on its
|
||||
* offered credit, AND this ack raises UWE but LWE is same
|
||||
* and below UWE at time of reneging (reduction)
|
||||
* Now, ISO 8073 12.2.3.8.3 says
|
||||
* that a retransmitted AK shall not contain the FCC
|
||||
* parameter. Now, how the hell you tell the difference
|
||||
* between a retransmitted ack and an ack that's sent in
|
||||
* response to a received ack, I don't know, because without
|
||||
* any local activity, and w/o any received DTs, they
|
||||
* will contain exactly the same credit/seq# information.
|
||||
* Anyway, given that the "retransmission of acks"
|
||||
* procedure (ISO 8073 12.2.3.8.3) is optional, and we
|
||||
* don't do it (although the peer can't tell that), we
|
||||
* ignore this last rule.
|
||||
*
|
||||
* We send FCC for reasons a) and b) only.
|
||||
* To add reason c) would require a ridiculous amount of state.
|
||||
*
|
||||
*/
|
||||
u_short bogus[4]; /* lwe(32), subseq(16), cdt(16) */
|
||||
SeqNum lwe;
|
||||
u_short subseq, fcredit;
|
||||
|
||||
tpcb->tp_sendfcc = 0;
|
||||
|
||||
lwe = (SeqNum) htonl(tpcb->tp_snduna);
|
||||
subseq = htons(tpcb->tp_r_subseq);
|
||||
fcredit = htons(tpcb->tp_fcredit);
|
||||
|
||||
bcopy((caddr_t) &lwe, (caddr_t)&bogus[0], sizeof(SeqNum));
|
||||
bcopy((caddr_t) &subseq, (caddr_t)&bogus[2], sizeof(u_short));
|
||||
bcopy((caddr_t) &fcredit, (caddr_t)&bogus[3], sizeof(u_short));
|
||||
|
||||
IFTRACE(D_ACKSEND)
|
||||
tptraceTPCB(TPPTmisc,
|
||||
"emit w/FCC: snduna r_subseq fcredit",
|
||||
tpcb->tp_snduna, tpcb->tp_r_subseq,
|
||||
tpcb->tp_fcredit, 0);
|
||||
ENDTRACE
|
||||
|
||||
IFDEBUG(D_ACKSEND)
|
||||
printf("Calling ADDOPTION 0x%x, 0x%x, 0x%x,0x%x\n",
|
||||
TPP_flow_cntl_conf,
|
||||
hdr, sizeof(bogus), bogus[0]);
|
||||
ENDDEBUG
|
||||
ADDOPTION(TPP_flow_cntl_conf, hdr, sizeof(bogus), bogus[0]);
|
||||
IFDEBUG(D_ACKSEND)
|
||||
printf("after ADDOPTION hdr 0x%x hdr->tpdu_li 0x%x\n",
|
||||
hdr, hdr->tpdu_li);
|
||||
printf(
|
||||
"after ADDOPTION csum_offset 0x%x, hdr->tpdu_li 0x%x\n",
|
||||
csum_offset, hdr->tpdu_li);
|
||||
ENDDEBUG
|
||||
|
||||
}
|
||||
tpcb->tp_reneged = 0;
|
||||
tpcb->tp_sent_rcvnxt = seq;
|
||||
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)
|
||||
printf(
|
||||
"2 after rADDOPTION csum_offset 0x%x, hdr->tpdu_li 0x%x\n",
|
||||
csum_offset, hdr->tpdu_li);
|
||||
ENDDEBUG
|
||||
break;
|
||||
|
||||
case ER_TPDU_type:
|
||||
hdr->tpdu_ERreason = eot;
|
||||
hdr->tpdu_cdt = 0;
|
||||
/* no user data */
|
||||
data = (struct mbuf *)0;
|
||||
IncStat(ts_ER_sent);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
ASSERT( ((int)hdr->tpdu_li > 0) && ((int)hdr->tpdu_li < MLEN) );
|
||||
|
||||
m->m_next = data;
|
||||
|
||||
ASSERT( hdr->tpdu_li < MLEN ); /* leave this in */
|
||||
ASSERT( hdr->tpdu_li != 0 ); /* leave this in */
|
||||
|
||||
m->m_len = hdr->tpdu_li ;
|
||||
hdr->tpdu_li --; /* doesn't include the li field */
|
||||
|
||||
datalen = m_datalen( m ); /* total len */
|
||||
|
||||
ASSERT( datalen <= tpcb->tp_l_tpdusize ); /* may become a problem
|
||||
when CLNP is used; leave in here for the time being */
|
||||
IFDEBUG(D_ACKSEND)
|
||||
printf(
|
||||
"4 after rADDOPTION csum_offset 0x%x, hdr->tpdu_li 0x%x\n",
|
||||
csum_offset, hdr->tpdu_li);
|
||||
ENDDEBUG
|
||||
if( datalen > tpcb->tp_l_tpdusize ) {
|
||||
printf("data len 0x%x tpcb->tp_l_tpdusize 0x%x\n",
|
||||
datalen, tpcb->tp_l_tpdusize);
|
||||
}
|
||||
IFDEBUG(D_EMIT)
|
||||
printf(
|
||||
"tp_emit before gen_csum m_len 0x%x, csum_offset 0x%x, datalen 0x%x\n",
|
||||
m->m_len, csum_offset, datalen);
|
||||
ENDDEBUG
|
||||
if( tpcb->tp_use_checksum ||
|
||||
(dutype == CR_TPDU_type && (tpcb->tp_class & TP_CLASS_4)) ) {
|
||||
iso_gen_csum(m, csum_offset, datalen);
|
||||
}
|
||||
|
||||
IFDEBUG(D_EMIT)
|
||||
printf("tp_emit before tpxxx_output tpcb 0x%x, dutype 0x%x, datalen 0x%x\n",
|
||||
tpcb, dutype, datalen);
|
||||
dump_buf(mtod(m, caddr_t), datalen);
|
||||
ENDDEBUG
|
||||
|
||||
IFPERF(tpcb)
|
||||
if( dutype == DT_TPDU_type ) {
|
||||
PStat(tpcb, Nb_to_ll) += (datalen - m->m_len);
|
||||
tpmeas( tpcb->tp_lref, TPtime_to_ll, (struct timeval *)0,
|
||||
seq, PStat(tpcb, Nb_to_ll), (datalen - m->m_len));
|
||||
}
|
||||
ENDPERF
|
||||
|
||||
IFTRACE(D_EMIT)
|
||||
tptraceTPCB(TPPTtpduout, dutype, hdr, hdr->tpdu_li+1, datalen, 0);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_EMIT)
|
||||
printf("OUTPUT: tpcb 0x%x, isop 0x%x, so 0x%x\n",
|
||||
tpcb, tpcb->tp_npcb, tpcb->tp_sock);
|
||||
ENDDEBUG
|
||||
|
||||
{ extern char tp_delay;
|
||||
|
||||
if( tp_delay )
|
||||
if( tpcb->tp_use_checksum == 0 ) {
|
||||
register u_int i = tp_delay;
|
||||
for (; i!= 0; i--)
|
||||
(void) iso_check_csum(m, datalen);
|
||||
}
|
||||
}
|
||||
ASSERT( m->m_len > 0 );
|
||||
error = (tpcb->tp_nlproto->nlp_output)(tpcb->tp_npcb, m, datalen,
|
||||
!tpcb->tp_use_checksum);
|
||||
IFDEBUG(D_EMIT)
|
||||
printf("OUTPUT: returned 0x%x\n", error);
|
||||
ENDDEBUG
|
||||
IFTRACE(D_EMIT)
|
||||
tptraceTPCB(TPPTmisc,
|
||||
"tp_emit nlproto->output netservice returns datalen",
|
||||
tpcb->tp_nlproto->nlp_output, tpcb->tp_netservice, error, datalen);
|
||||
ENDTRACE
|
||||
done:
|
||||
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;
|
||||
}
|
||||
/*
|
||||
* NAME: tp_error_emit()
|
||||
* CALLED FROM: tp_input() when a DR or ER is to be issued in
|
||||
* response to an input error.
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* The error type is the first argument.
|
||||
* The argument (sref) is the source reference on the bad incoming tpdu,
|
||||
* and is used for a destination reference on the outgoing packet.
|
||||
* (faddr) and (laddr) are the foreign and local addresses for this
|
||||
* connection.
|
||||
* (erdata) is a ptr to the errant incoming tpdu, and is copied into the
|
||||
* outgoing ER, if an ER is to be issued.
|
||||
* (erlen) is the number of octets of the errant tpdu that we should
|
||||
* try to copy.
|
||||
* (tpcb) is the pcb that describes the connection for which the bad tpdu
|
||||
* arrived.
|
||||
* RETURN VALUES:
|
||||
* 0 OK
|
||||
* ENOBUFS
|
||||
* E* from net layer datagram output routine
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
|
||||
int
|
||||
tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
|
||||
dgout_routine)
|
||||
int error;
|
||||
u_long sref;
|
||||
struct sockaddr_iso *faddr, *laddr;
|
||||
struct mbuf *erdata;
|
||||
int erlen;
|
||||
struct tp_pcb *tpcb;
|
||||
caddr_t cons_channel;
|
||||
int (*dgout_routine)();
|
||||
{
|
||||
int dutype;
|
||||
int datalen = 0;
|
||||
register struct tpdu *hdr;
|
||||
register struct mbuf *m;
|
||||
int csum_offset;
|
||||
|
||||
IFTRACE(D_ERROR_EMIT)
|
||||
tptrace(TPPTmisc, "tp_error_emit error sref tpcb erlen",
|
||||
error, sref, tpcb, erlen);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_ERROR_EMIT)
|
||||
printf(
|
||||
"tp_error_emit error 0x%x sref 0x%x tpcb 0x%x erlen 0x%x chan 0x%x\n",
|
||||
error, sref, tpcb, erlen, cons_channel);
|
||||
ENDDEBUG
|
||||
|
||||
MGET(m, M_DONTWAIT, TPMT_TPHDR);
|
||||
if (m == NULL) {
|
||||
return ENOBUFS;
|
||||
}
|
||||
m->m_len = sizeof(struct tpdu);
|
||||
m->m_act = MNULL;
|
||||
|
||||
hdr = mtod(m, struct tpdu *);
|
||||
|
||||
IFDEBUG(D_ERROR_EMIT)
|
||||
printf("[error 0x%x] [error&0xff 0x%x] [(char)error 0x%x]\n",
|
||||
error, error&0xff, (char)error);
|
||||
ENDDEBUG
|
||||
|
||||
|
||||
if (error & TP_ERROR_SNDC)
|
||||
dutype = DC_TPDU_type;
|
||||
else if (error & 0x40) {
|
||||
error &= ~0x40;
|
||||
dutype = ER_TPDU_type;
|
||||
} else
|
||||
dutype = DR_TPDU_type;
|
||||
error &= 0xff;
|
||||
|
||||
hdr->tpdu_type = dutype;
|
||||
hdr->tpdu_cdt = 0;
|
||||
|
||||
switch( dutype ) {
|
||||
|
||||
case DC_TPDU_type:
|
||||
IncStat(ts_DC_sent);
|
||||
hdr->tpdu_li = 6;
|
||||
hdr->tpdu_DCdref = htons(sref);
|
||||
hdr->tpdu_DCsref = tpcb ? htons(tpcb->tp_lref) : 0;
|
||||
IFDEBUG(D_ERROR_EMIT)
|
||||
printf("DC case:\n");
|
||||
dump_buf( hdr, 6);
|
||||
ENDDEBUG
|
||||
/* forget the add'l information variable part */
|
||||
break;
|
||||
|
||||
case DR_TPDU_type:
|
||||
IncStat(ts_DR_sent);
|
||||
hdr->tpdu_li = 7;
|
||||
hdr->tpdu_DRdref = htons(sref);
|
||||
hdr->tpdu_DRsref = 0;
|
||||
hdr->tpdu_DRreason = (char)error;
|
||||
IFDEBUG(D_ERROR_EMIT)
|
||||
printf("DR case:\n");
|
||||
dump_buf( hdr, 7);
|
||||
ENDDEBUG
|
||||
/* forget the add'l information variable part */
|
||||
break;
|
||||
|
||||
case ER_TPDU_type:
|
||||
IncStat(ts_ER_sent);
|
||||
hdr->tpdu_li = 5;
|
||||
hdr->tpdu_ERreason = (char)error;
|
||||
hdr->tpdu_ERdref = htons(sref);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(0);
|
||||
printf("TP PANIC: bad dutype 0x%x\n", dutype);
|
||||
}
|
||||
|
||||
if(tpcb)
|
||||
if( tpcb->tp_use_checksum ) {
|
||||
ADDOPTION(TPP_checksum, hdr, 2, csum_offset /* dummy argument */);
|
||||
csum_offset = hdr->tpdu_li - 2;
|
||||
}
|
||||
|
||||
ASSERT( hdr->tpdu_li < MLEN );
|
||||
|
||||
if (dutype == ER_TPDU_type) {
|
||||
/* copy the errant tpdu into another 'variable part' */
|
||||
register caddr_t P;
|
||||
|
||||
IFTRACE(D_ERROR_EMIT)
|
||||
tptrace(TPPTmisc, "error_emit ER len tpduli", erlen, hdr->tpdu_li,
|
||||
0,0);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_ERROR_EMIT)
|
||||
printf("error_emit ER len 0x%x tpduli 0x%x\n", erlen, hdr->tpdu_li);
|
||||
ENDDEBUG
|
||||
|
||||
/* copy at most as many octets for which you have room */
|
||||
if (erlen + hdr->tpdu_li + 2 > TP_MAX_HEADER_LEN)
|
||||
erlen = TP_MAX_HEADER_LEN - hdr->tpdu_li - 2;
|
||||
|
||||
/* add the "invalid tpdu" parameter : required in class 0 */
|
||||
P = (caddr_t)hdr + (int)(hdr->tpdu_li);
|
||||
vbptr(P)->tpv_code = TPP_invalid_tpdu; /* parameter code */
|
||||
vbptr(P)->tpv_len = erlen; /* parameter length */
|
||||
m->m_len = hdr->tpdu_li + 2; /* 1 for code, 1 for length */
|
||||
|
||||
/* tp_input very likely handed us an mbuf chain w/ nothing in
|
||||
* the first mbuf and the data following the empty mbuf
|
||||
*/
|
||||
if(erdata->m_len == 0) {
|
||||
erdata = m_free(erdata); /* returns the next mbuf on the chain */
|
||||
}
|
||||
/*
|
||||
* copy only up to the bad octet
|
||||
* (or max that will fit in a header
|
||||
*/
|
||||
m->m_next = m_copy(erdata, 0, erlen);
|
||||
hdr->tpdu_li += erlen + 2;
|
||||
m_freem(erdata);
|
||||
} else {
|
||||
IFDEBUG(D_ERROR_EMIT)
|
||||
printf("error_emit DR error tpduli 0x%x\n", error, hdr->tpdu_li);
|
||||
dump_buf( (char *)hdr, hdr->tpdu_li );
|
||||
ENDDEBUG
|
||||
m->m_len = hdr->tpdu_li ;
|
||||
m_freem(erdata);
|
||||
}
|
||||
|
||||
hdr->tpdu_li --;
|
||||
IFTRACE(D_ERROR_EMIT)
|
||||
tptrace(TPPTtpduout, 2, hdr, hdr->tpdu_li+1, 0, 0);
|
||||
ENDTRACE
|
||||
|
||||
datalen = m_datalen( m);
|
||||
if (tpcb) {
|
||||
if( tpcb->tp_use_checksum ) {
|
||||
IFTRACE(D_ERROR_EMIT)
|
||||
tptrace(TPPTmisc, "before gen csum datalen", datalen,0,0,0);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_ERROR_EMIT)
|
||||
printf("before gen csum datalen 0x%x, csum_offset 0x%x\n",
|
||||
datalen, csum_offset);
|
||||
ENDDEBUG
|
||||
|
||||
iso_gen_csum(m, csum_offset, datalen);
|
||||
}
|
||||
|
||||
IFDEBUG(D_ERROR_EMIT)
|
||||
printf("OUTPUT: tpcb 0x%x, isop 0x%x, so 0x%x\n",
|
||||
tpcb, tpcb->tp_npcb, tpcb->tp_sock);
|
||||
ENDDEBUG
|
||||
}
|
||||
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");
|
||||
dump_addr((struct sockaddr *)laddr);
|
||||
printf("Faddr\n");
|
||||
dump_addr((struct sockaddr *)faddr);
|
||||
ENDDEBUG
|
||||
return (tpcb->tp_nlproto->nlp_dgoutput)(
|
||||
&laddr->siso_addr,
|
||||
&faddr->siso_addr,
|
||||
m, datalen,
|
||||
/* no route */ (caddr_t)0, !tpcb->tp_use_checksum);
|
||||
} 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 {
|
||||
IFDEBUG(D_ERROR_EMIT)
|
||||
printf("tp_error_emit DROPPING \n", m);
|
||||
ENDDEBUG
|
||||
IncStat(ts_send_drop);
|
||||
m_freem(m);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* $Id: tp_events.h,v 1.3 1994/08/21 06:14:24 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_EVENTS_H_
|
||||
#define _NETISO_TP_EVENTS_H_
|
||||
|
||||
struct tp_event {
|
||||
int ev_number;
|
||||
struct timeval e_time;
|
||||
#define TM_inact 0x0
|
||||
#define TM_retrans 0x1
|
||||
#define TM_sendack 0x2
|
||||
#define TM_notused 0x3
|
||||
|
||||
union{
|
||||
struct { SeqNum e_low; SeqNum e_high; int e_retrans; } EV_TM_reference;
|
||||
|
||||
#define TM_reference 0x4
|
||||
struct { SeqNum e_low; SeqNum e_high; int e_retrans; } EV_TM_data_retrans;
|
||||
|
||||
#define TM_data_retrans 0x5
|
||||
struct {
|
||||
u_char e_reason;
|
||||
} EV_ER_TPDU;
|
||||
|
||||
#define ER_TPDU 0x6
|
||||
struct { struct mbuf *e_data; /* first field */
|
||||
int e_datalen; /* 2nd field */
|
||||
u_int e_cdt;
|
||||
} EV_CR_TPDU;
|
||||
|
||||
#define CR_TPDU 0x7
|
||||
struct { struct mbuf *e_data; /* first field */
|
||||
int e_datalen; /* 2nd field */
|
||||
u_short e_sref;
|
||||
u_char e_reason;
|
||||
} EV_DR_TPDU;
|
||||
|
||||
#define DR_TPDU 0x8
|
||||
#define DC_TPDU 0x9
|
||||
struct { struct mbuf *e_data; /* first field */
|
||||
int e_datalen; /* 2nd field */
|
||||
u_short e_sref;
|
||||
u_int e_cdt;
|
||||
} EV_CC_TPDU;
|
||||
|
||||
#define CC_TPDU 0xa
|
||||
struct { u_int e_cdt;
|
||||
SeqNum e_seq;
|
||||
SeqNum e_subseq;
|
||||
u_char e_fcc_present;
|
||||
} EV_AK_TPDU;
|
||||
|
||||
#define AK_TPDU 0xb
|
||||
struct { struct mbuf *e_data; /* first field */
|
||||
int e_datalen; /* 2nd field */
|
||||
u_int e_eot;
|
||||
SeqNum e_seq;
|
||||
} EV_DT_TPDU;
|
||||
|
||||
#define DT_TPDU 0xc
|
||||
struct { struct mbuf *e_data; /* first field */
|
||||
int e_datalen; /* 2nd field */
|
||||
SeqNum e_seq;
|
||||
} EV_XPD_TPDU;
|
||||
|
||||
#define XPD_TPDU 0xd
|
||||
struct { SeqNum e_seq; } EV_XAK_TPDU;
|
||||
|
||||
#define XAK_TPDU 0xe
|
||||
#define T_CONN_req 0xf
|
||||
struct { u_char e_reason; } EV_T_DISC_req;
|
||||
|
||||
#define T_DISC_req 0x10
|
||||
#define T_LISTEN_req 0x11
|
||||
#define T_DATA_req 0x12
|
||||
#define T_XPD_req 0x13
|
||||
#define T_USR_rcvd 0x14
|
||||
#define T_USR_Xrcvd 0x15
|
||||
#define T_DETACH 0x16
|
||||
#define T_NETRESET 0x17
|
||||
#define T_ACPT_req 0x18
|
||||
}ev_union;
|
||||
};/* end struct event */
|
||||
|
||||
#define tp_NEVENTS 0x19
|
||||
|
||||
#define ATTR(X)ev_union.EV_/**/X/**/
|
||||
|
||||
#endif
|
||||
@@ -1,691 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_inet.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_inet.c,v 1.4 1995/04/26 21:32:36 pst Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_inet.c,v 1.4 1995/04/26 21:32:36 pst Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_inet.c,v $
|
||||
*
|
||||
* 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
|
||||
* through a switch table (struct nl_protosw *) tpcb->tp_nlproto
|
||||
* (see tp_pcb.c).
|
||||
* The routines here are:
|
||||
* in_getsufx: gets transport suffix out of an inpcb structure.
|
||||
* in_putsufx: put transport suffix into an inpcb structure.
|
||||
* in_putnetaddr: put a whole net addr into an inpcb.
|
||||
* in_getnetaddr: get a whole net addr from an inpcb.
|
||||
* in_cmpnetaddr: compare a whole net addr from an isopcb.
|
||||
* in_recycle_suffix: clear suffix for reuse in inpcb
|
||||
* tpip_mtu: figure out what size tpdu to use
|
||||
* tpip_input: take a pkt from ip, strip off its ip header, give to tp
|
||||
* tpip_output_dg: package a pkt for ip given 2 addresses & some data
|
||||
* tpip_output: package a pkt for ip given an inpcb & some data
|
||||
*/
|
||||
|
||||
#ifdef INET
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netiso/tp_param.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_ip.h>
|
||||
#include <netiso/tp_pcb.h>
|
||||
#include <netiso/tp_trace.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_tpdu.h>
|
||||
#include <netinet/in_var.h>
|
||||
|
||||
#ifndef ISO
|
||||
#include <netiso/iso_chksum.c>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NAME: in_getsufx()
|
||||
|
||||
* CALLED FROM: pr_usrreq() on PRU_BIND,
|
||||
* PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
|
||||
*
|
||||
* FUNCTION, ARGUMENTS, and RETURN VALUE:
|
||||
* Get a transport suffix from an inpcb structure (inp).
|
||||
* The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
|
||||
*
|
||||
* RETURNS: internet port / transport suffix
|
||||
* (CAST TO AN INT)
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
in_getsufx(inp, lenp, data_out, which)
|
||||
struct inpcb *inp;
|
||||
u_short *lenp;
|
||||
caddr_t data_out;
|
||||
int which;
|
||||
{
|
||||
*lenp = sizeof(u_short);
|
||||
switch (which) {
|
||||
case TP_LOCAL:
|
||||
*(u_short *)data_out = inp->inp_lport;
|
||||
return;
|
||||
|
||||
case TP_FOREIGN:
|
||||
*(u_short *)data_out = inp->inp_fport;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: in_putsufx()
|
||||
*
|
||||
* CALLED FROM: tp_newsocket(); i.e., when a connection
|
||||
* is being established by an incoming CR_TPDU.
|
||||
*
|
||||
* FUNCTION, ARGUMENTS:
|
||||
* Put a transport suffix (found in name) into an inpcb structure (inp).
|
||||
* The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
|
||||
*
|
||||
* RETURNS: Nada
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
in_putsufx(inp, sufxloc, sufxlen, which)
|
||||
struct inpcb *inp;
|
||||
caddr_t sufxloc;
|
||||
int which;
|
||||
{
|
||||
if (which == TP_FOREIGN) {
|
||||
bcopy(sufxloc, (caddr_t)&inp->inp_fport, sizeof(inp->inp_fport));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: in_recycle_tsuffix()
|
||||
*
|
||||
* CALLED FROM: tp.trans whenever we go into REFWAIT state.
|
||||
*
|
||||
* FUNCTION and ARGUMENT:
|
||||
* Called when a ref is frozen, to allow the suffix to be reused.
|
||||
* (inp) is the net level pcb.
|
||||
*
|
||||
* RETURNS: Nada
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES: This really shouldn't have to be done in a NET level pcb
|
||||
* but... for the internet world that just the way it is done in BSD...
|
||||
* The alternative is to have the port unusable until the reference
|
||||
* timer goes off.
|
||||
*/
|
||||
void
|
||||
in_recycle_tsuffix(inp)
|
||||
struct inpcb *inp;
|
||||
{
|
||||
inp->inp_fport = inp->inp_lport = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: in_putnetaddr()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* tp_newsocket(); i.e., when a connection is being established by an
|
||||
* incoming CR_TPDU.
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Copy a whole net addr from a struct sockaddr (name).
|
||||
* into an inpcb (inp).
|
||||
* The argument (which) takes values TP_LOCAL or TP_FOREIGN
|
||||
*
|
||||
* RETURNS: Nada
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
void
|
||||
in_putnetaddr(inp, name, which)
|
||||
register struct inpcb *inp;
|
||||
struct sockaddr_in *name;
|
||||
int which;
|
||||
{
|
||||
switch (which) {
|
||||
case TP_LOCAL:
|
||||
bcopy((caddr_t)&name->sin_addr,
|
||||
(caddr_t)&inp->inp_laddr, sizeof(struct in_addr));
|
||||
/* won't work if the dst address (name) is INADDR_ANY */
|
||||
|
||||
break;
|
||||
case TP_FOREIGN:
|
||||
if( name != (struct sockaddr_in *)0 ) {
|
||||
bcopy((caddr_t)&name->sin_addr,
|
||||
(caddr_t)&inp->inp_faddr, sizeof(struct in_addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: in_putnetaddr()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* tp_input() when a connection is being established by an
|
||||
* incoming CR_TPDU, and considered for interception.
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Compare a whole net addr from a struct sockaddr (name),
|
||||
* with that implicitly stored in an inpcb (inp).
|
||||
* The argument (which) takes values TP_LOCAL or TP_FOREIGN
|
||||
*
|
||||
* RETURNS: Nada
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
in_cmpnetaddr(inp, name, which)
|
||||
register struct inpcb *inp;
|
||||
register struct sockaddr_in *name;
|
||||
int which;
|
||||
{
|
||||
if (which == TP_LOCAL) {
|
||||
if (name->sin_port && name->sin_port != inp->inp_lport)
|
||||
return 0;
|
||||
return (name->sin_addr.s_addr == inp->inp_laddr.s_addr);
|
||||
}
|
||||
if (name->sin_port && name->sin_port != inp->inp_fport)
|
||||
return 0;
|
||||
return (name->sin_addr.s_addr == inp->inp_faddr.s_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: in_getnetaddr()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Copy a whole net addr from an inpcb (inp) into
|
||||
* an mbuf (name);
|
||||
* The argument (which) takes values TP_LOCAL or TP_FOREIGN.
|
||||
*
|
||||
* RETURNS: Nada
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
|
||||
void
|
||||
in_getnetaddr( inp, name, which)
|
||||
register struct mbuf *name;
|
||||
struct inpcb *inp;
|
||||
int which;
|
||||
{
|
||||
register struct sockaddr_in *sin = mtod(name, struct sockaddr_in *);
|
||||
bzero((caddr_t)sin, sizeof(*sin));
|
||||
switch (which) {
|
||||
case TP_LOCAL:
|
||||
sin->sin_addr = inp->inp_laddr;
|
||||
sin->sin_port = inp->inp_lport;
|
||||
break;
|
||||
case TP_FOREIGN:
|
||||
sin->sin_addr = inp->inp_faddr;
|
||||
sin->sin_port = inp->inp_fport;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
name->m_len = sin->sin_len = sizeof (*sin);
|
||||
sin->sin_family = AF_INET;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: tpip_mtu()
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
* Sets tp_routep pointer in pcb.
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
|
||||
tpip_mtu(tpcb)
|
||||
register struct tp_pcb *tpcb;
|
||||
{
|
||||
struct inpcb *inp = (struct inpcb *)tpcb->tp_npcb;
|
||||
|
||||
IFDEBUG(D_CONN)
|
||||
printf("tpip_mtu(tpcb)\n", tpcb);
|
||||
printf("tpip_mtu routing to addr 0x%x\n", inp->inp_faddr.s_addr);
|
||||
ENDDEBUG
|
||||
tpcb->tp_routep = &(inp->inp_route.ro_rt);
|
||||
return (sizeof (struct ip));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: tpip_output()
|
||||
*
|
||||
* CALLED FROM: tp_emit()
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Take a packet(m0) from tp and package it so that ip will accept it.
|
||||
* This means prepending space for the ip header and filling in a few
|
||||
* of the fields.
|
||||
* inp is the inpcb structure; datalen is the length of the data in the
|
||||
* mbuf string m0.
|
||||
* RETURNS:
|
||||
* whatever (E*) is returned form the net layer output routine.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
|
||||
int
|
||||
tpip_output(inp, m0, datalen, nochksum)
|
||||
struct inpcb *inp;
|
||||
struct mbuf *m0;
|
||||
int datalen;
|
||||
int nochksum;
|
||||
{
|
||||
return tpip_output_dg( &inp->inp_laddr, &inp->inp_faddr, m0, datalen,
|
||||
&inp->inp_route, nochksum);
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: tpip_output_dg()
|
||||
*
|
||||
* CALLED FROM: tp_error_emit()
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* This is a copy of tpip_output that takes the addresses
|
||||
* instead of a pcb. It's used by the tp_error_emit, when we
|
||||
* don't have an in_pcb with which to call the normal output rtn.
|
||||
*
|
||||
* RETURNS: ENOBUFS or whatever (E*) is
|
||||
* returned form the net layer output routine.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
tpip_output_dg(laddr, faddr, m0, datalen, ro, nochksum)
|
||||
struct in_addr *laddr, *faddr;
|
||||
struct mbuf *m0;
|
||||
int datalen;
|
||||
struct route *ro;
|
||||
int nochksum;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
register struct ip *ip;
|
||||
int error;
|
||||
|
||||
IFDEBUG(D_EMIT)
|
||||
printf("tpip_output_dg datalen 0x%x m0 0x%x\n", datalen, m0);
|
||||
ENDDEBUG
|
||||
|
||||
|
||||
MGETHDR(m, M_DONTWAIT, TPMT_IPHDR);
|
||||
if (m == 0) {
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
}
|
||||
m->m_next = m0;
|
||||
MH_ALIGN(m, sizeof(struct ip));
|
||||
m->m_len = sizeof(struct ip);
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
bzero((caddr_t)ip, sizeof *ip);
|
||||
|
||||
ip->ip_p = IPPROTO_TP;
|
||||
m->m_pkthdr.len = ip->ip_len = sizeof(struct ip) + datalen;
|
||||
ip->ip_ttl = MAXTTL;
|
||||
/* don't know why you need to set ttl;
|
||||
* overlay doesn't even make this available
|
||||
*/
|
||||
|
||||
ip->ip_src = *laddr;
|
||||
ip->ip_dst = *faddr;
|
||||
|
||||
IncStat(ts_tpdu_sent);
|
||||
IFDEBUG(D_EMIT)
|
||||
dump_mbuf(m, "tpip_output_dg before ip_output\n");
|
||||
ENDDEBUG
|
||||
|
||||
error = ip_output(m, (struct mbuf *)0, ro, IP_ALLOWBROADCAST, NULL);
|
||||
|
||||
IFDEBUG(D_EMIT)
|
||||
printf("tpip_output_dg after ip_output\n");
|
||||
ENDDEBUG
|
||||
|
||||
return error;
|
||||
|
||||
bad:
|
||||
m_freem(m);
|
||||
IncStat(ts_send_drop);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: tpip_input()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* ip's input routine, indirectly through the protosw.
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Take a packet (m) from ip, strip off the ip header and give it to tp
|
||||
*
|
||||
* RETURNS: No return value.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
ProtoHook
|
||||
tpip_input(m, iplen)
|
||||
struct mbuf *m;
|
||||
int iplen;
|
||||
{
|
||||
struct sockaddr_in src, dst;
|
||||
register struct ip *ip;
|
||||
int s = splnet(), hdrlen;
|
||||
|
||||
IncStat(ts_pkt_rcvd);
|
||||
|
||||
/*
|
||||
* IP layer has already pulled up the IP header,
|
||||
* but the first byte after the IP header may not be there,
|
||||
* e.g. if you came in via loopback, so you have to do an
|
||||
* m_pullup to before you can even look to see how much you
|
||||
* really need. The good news is that m_pullup will round
|
||||
* up to almost the next mbuf's worth.
|
||||
*/
|
||||
|
||||
|
||||
if((m = m_pullup(m, iplen + 1)) == MNULL)
|
||||
goto discard;
|
||||
CHANGE_MTYPE(m, TPMT_DATA);
|
||||
|
||||
/*
|
||||
* Now pull up the whole tp header:
|
||||
* Unfortunately, there may be IP options to skip past so we
|
||||
* just fetch it as an unsigned char.
|
||||
*/
|
||||
hdrlen = iplen + 1 + mtod(m, u_char *)[iplen];
|
||||
|
||||
if( m->m_len < hdrlen ) {
|
||||
if((m = m_pullup(m, hdrlen)) == MNULL){
|
||||
IFDEBUG(D_TPINPUT)
|
||||
printf("tp_input, pullup 2!\n");
|
||||
ENDDEBUG
|
||||
goto discard;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* cannot use tp_inputprep() here 'cause you don't
|
||||
* have quite the same situation
|
||||
*/
|
||||
|
||||
IFDEBUG(D_TPINPUT)
|
||||
dump_mbuf(m, "after tpip_input both pullups");
|
||||
ENDDEBUG
|
||||
/*
|
||||
* m_pullup may have returned a different mbuf
|
||||
*/
|
||||
ip = mtod(m, struct ip *);
|
||||
|
||||
/*
|
||||
* drop the ip header from the front of the mbuf
|
||||
* this is necessary for the tp checksum
|
||||
*/
|
||||
m->m_len -= iplen;
|
||||
m->m_data += iplen;
|
||||
|
||||
src.sin_addr = *(struct in_addr *)&(ip->ip_src);
|
||||
src.sin_family = AF_INET;
|
||||
src.sin_len = sizeof(src);
|
||||
dst.sin_addr = *(struct in_addr *)&(ip->ip_dst);
|
||||
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;
|
||||
|
||||
discard:
|
||||
IFDEBUG(D_TPINPUT)
|
||||
printf("tpip_input DISCARD\n");
|
||||
ENDDEBUG
|
||||
IFTRACE(D_TPINPUT)
|
||||
tptrace(TPPTmisc, "tpip_input DISCARD m", m,0,0,0);
|
||||
ENDTRACE
|
||||
m_freem(m);
|
||||
IncStat(ts_recv_drop);
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <sys/protosw.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
|
||||
extern void tp_quench();
|
||||
/*
|
||||
* NAME: tpin_quench()
|
||||
*
|
||||
* CALLED FROM: tpip_ctlinput()
|
||||
*
|
||||
* FUNCTION and ARGUMENTS: find the tpcb pointer and pass it to tp_quench
|
||||
*
|
||||
* RETURNS: Nada
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
|
||||
void
|
||||
tpin_quench(inp)
|
||||
struct inpcb *inp;
|
||||
{
|
||||
tp_quench((struct tp_pcb *)inp->inp_socket->so_pcb, PRC_QUENCH);
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: tpip_ctlinput()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* The network layer through the protosw table.
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* When clnp gets an ICMP msg this gets called.
|
||||
* It either returns an error status to the user or
|
||||
* causes all connections on this address to be aborted
|
||||
* by calling the appropriate xx_notify() routine.
|
||||
* (cmd) is the type of ICMP error.
|
||||
* (sa) the address of the sender
|
||||
*
|
||||
* RETURNS: Nothing
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
ProtoHook
|
||||
tpip_ctlinput(cmd, sin)
|
||||
int cmd;
|
||||
struct sockaddr_in *sin;
|
||||
{
|
||||
extern u_char inetctlerrmap[];
|
||||
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;
|
||||
if (sin->sin_addr.s_addr == INADDR_ANY)
|
||||
return 0;
|
||||
if (cmd < 0 || cmd > PRC_NCMDS)
|
||||
return 0;
|
||||
switch (cmd) {
|
||||
|
||||
case PRC_QUENCH:
|
||||
in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,
|
||||
zeroin_addr, 0, cmd, tp_quench);
|
||||
break;
|
||||
|
||||
case PRC_ROUTEDEAD:
|
||||
case PRC_HOSTUNREACH:
|
||||
case PRC_UNREACH_NET:
|
||||
case PRC_IFDOWN:
|
||||
case PRC_HOSTDEAD:
|
||||
in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,
|
||||
zeroin_addr, 0, cmd, in_rtchange);
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
case PRC_MSGSIZE:
|
||||
case PRC_UNREACH_HOST:
|
||||
case PRC_UNREACH_PROTOCOL:
|
||||
case PRC_UNREACH_PORT:
|
||||
case PRC_UNREACH_NEEDFRAG:
|
||||
case PRC_UNREACH_SRCFAIL:
|
||||
case PRC_REDIRECT_NET:
|
||||
case PRC_REDIRECT_HOST:
|
||||
case PRC_REDIRECT_TOSNET:
|
||||
case PRC_REDIRECT_TOSHOST:
|
||||
case PRC_TIMXCEED_INTRANS:
|
||||
case PRC_TIMXCEED_REASS:
|
||||
case PRC_PARAMPROB:
|
||||
*/
|
||||
in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,
|
||||
zeroin_addr, 0, cmd, tpin_abort);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: tpin_abort()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* xxx_notify() from tp_ctlinput() when
|
||||
* net level gets some ICMP-equiv. type event.
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Cause the connection to be aborted with some sort of error
|
||||
* reason indicating that the network layer caused the abort.
|
||||
* Fakes an ER TPDU so we can go through the driver.
|
||||
*
|
||||
* RETURNS: Nothing
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
|
||||
ProtoHook
|
||||
tpin_abort(inp)
|
||||
struct inpcb *inp;
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef ARGO_DEBUG
|
||||
dump_inaddr(addr)
|
||||
register struct sockaddr_in *addr;
|
||||
{
|
||||
printf("INET: port 0x%x; addr 0x%x\n", addr->sin_port, addr->sin_addr);
|
||||
}
|
||||
#endif /* ARGO_DEBUG */
|
||||
#endif /* INET */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,91 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_ip.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_ip.h,v 1.3 1994/08/21 06:14:24 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_IP_H_
|
||||
#define _NETISO_TP_IP_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_ip.h,v 1.3 1994/08/21 06:14:24 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_ip.h,v $
|
||||
*
|
||||
* internet IP-dependent structures and include files
|
||||
*
|
||||
*/
|
||||
|
||||
#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
|
||||
@@ -1,694 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_iso.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_iso.c,v 1.2 1994/08/02 07:51:14 davidg Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_iso.c,v 1.2 1994/08/02 07:51:14 davidg Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_iso.c,v $
|
||||
*
|
||||
* 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
|
||||
* through a switch table (struct nl_protosw *) tpcb->tp_nlproto
|
||||
* (see tp_pcb.c).
|
||||
* The routines here are:
|
||||
* iso_getsufx: gets transport suffix out of an isopcb structure.
|
||||
* iso_putsufx: put transport suffix into an isopcb structure.
|
||||
* iso_putnetaddr: put a whole net addr into an isopcb.
|
||||
* iso_getnetaddr: get a whole net addr from an isopcb.
|
||||
* iso_cmpnetaddr: compare a whole net addr from an isopcb.
|
||||
* iso_recycle_suffix: clear suffix for reuse in isopcb
|
||||
* tpclnp_ctlinput: handle ER CNLPdu : icmp-like stuff
|
||||
* tpclnp_mtu: figure out what size tpdu to use
|
||||
* tpclnp_input: take a pkt from clnp, strip off its clnp header,
|
||||
* give to tp
|
||||
* tpclnp_output_dg: package a pkt for clnp given 2 addresses & some data
|
||||
* tpclnp_output: package a pkt for clnp given an isopcb & some data
|
||||
*/
|
||||
|
||||
#ifdef ISO
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/protosw.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_param.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_pcb.h>
|
||||
#include <netiso/tp_trace.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_tpdu.h>
|
||||
#include <netiso/tp_clnp.h>
|
||||
#include <netiso/cltp_var.h>
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* pr_usrreq() on PRU_BIND, PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
|
||||
* FUNCTION, ARGUMENTS:
|
||||
* The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
|
||||
*/
|
||||
|
||||
iso_getsufx(isop, lenp, data_out, which)
|
||||
struct isopcb *isop;
|
||||
u_short *lenp;
|
||||
caddr_t data_out;
|
||||
int which;
|
||||
{
|
||||
register struct sockaddr_iso *addr = 0;
|
||||
|
||||
switch (which) {
|
||||
case TP_LOCAL:
|
||||
addr = isop->isop_laddr;
|
||||
break;
|
||||
|
||||
case TP_FOREIGN:
|
||||
addr = isop->isop_faddr;
|
||||
}
|
||||
if (addr)
|
||||
bcopy(TSEL(addr), data_out, (*lenp = addr->siso_tlen));
|
||||
}
|
||||
|
||||
/* CALLED FROM:
|
||||
* tp_newsocket(); i.e., when a connection is being established by an
|
||||
* incoming CR_TPDU.
|
||||
*
|
||||
* FUNCTION, ARGUMENTS:
|
||||
* Put a transport suffix (found in name) into an isopcb structure (isop).
|
||||
* The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
|
||||
*/
|
||||
void
|
||||
iso_putsufx(isop, sufxloc, sufxlen, which)
|
||||
struct isopcb *isop;
|
||||
caddr_t sufxloc;
|
||||
int sufxlen, which;
|
||||
{
|
||||
struct sockaddr_iso **dst, *backup;
|
||||
register struct sockaddr_iso *addr;
|
||||
struct mbuf *m;
|
||||
int len;
|
||||
|
||||
switch (which) {
|
||||
default:
|
||||
return;
|
||||
|
||||
case TP_LOCAL:
|
||||
dst = &isop->isop_laddr;
|
||||
backup = &isop->isop_sladdr;
|
||||
break;
|
||||
|
||||
case TP_FOREIGN:
|
||||
dst = &isop->isop_faddr;
|
||||
backup = &isop->isop_sfaddr;
|
||||
}
|
||||
if ((addr = *dst) == 0) {
|
||||
addr = *dst = backup;
|
||||
addr->siso_nlen = 0;
|
||||
addr->siso_slen = 0;
|
||||
addr->siso_plen = 0;
|
||||
printf("iso_putsufx on un-initialized isopcb\n");
|
||||
}
|
||||
len = sufxlen + addr->siso_nlen +
|
||||
(sizeof(*addr) - sizeof(addr->siso_data));
|
||||
if (addr == backup) {
|
||||
if (len > sizeof(*addr)) {
|
||||
m = m_getclr(M_DONTWAIT, MT_SONAME);
|
||||
if (m == 0)
|
||||
return;
|
||||
addr = *dst = mtod(m, struct sockaddr_iso *);
|
||||
*addr = *backup;
|
||||
m->m_len = len;
|
||||
}
|
||||
}
|
||||
bcopy(sufxloc, TSEL(addr), sufxlen);
|
||||
addr->siso_tlen = sufxlen;
|
||||
addr->siso_len = len;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp.trans whenever we go into REFWAIT state.
|
||||
* FUNCTION and ARGUMENT:
|
||||
* Called when a ref is frozen, to allow the suffix to be reused.
|
||||
* (isop) is the net level pcb. This really shouldn't have to be
|
||||
* done in a NET level pcb but... for the internet world that just
|
||||
* the way it is done in BSD...
|
||||
* The alternative is to have the port unusable until the reference
|
||||
* timer goes off.
|
||||
*/
|
||||
void
|
||||
iso_recycle_tsuffix(isop)
|
||||
struct isopcb *isop;
|
||||
{
|
||||
isop->isop_laddr->siso_tlen = isop->isop_faddr->siso_tlen = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_newsocket(); i.e., when a connection is being established by an
|
||||
* incoming CR_TPDU.
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Copy a whole net addr from a struct sockaddr (name).
|
||||
* into an isopcb (isop).
|
||||
* The argument (which) takes values TP_LOCAL or TP_FOREIGN
|
||||
*/
|
||||
void
|
||||
iso_putnetaddr(isop, name, which)
|
||||
register struct isopcb *isop;
|
||||
struct sockaddr_iso *name;
|
||||
int which;
|
||||
{
|
||||
struct sockaddr_iso **sisop, *backup;
|
||||
register struct sockaddr_iso *siso;
|
||||
|
||||
switch (which) {
|
||||
default:
|
||||
printf("iso_putnetaddr: should panic\n");
|
||||
return;
|
||||
case TP_LOCAL:
|
||||
sisop = &isop->isop_laddr;
|
||||
backup = &isop->isop_sladdr;
|
||||
break;
|
||||
case TP_FOREIGN:
|
||||
sisop = &isop->isop_faddr;
|
||||
backup = &isop->isop_sfaddr;
|
||||
}
|
||||
siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
|
||||
IFDEBUG(D_TPISO)
|
||||
printf("ISO_PUTNETADDR\n");
|
||||
dump_isoaddr(isop->isop_faddr);
|
||||
ENDDEBUG
|
||||
siso->siso_addr = name->siso_addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_input() when a connection is being established by an
|
||||
* incoming CR_TPDU, and considered for interception.
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* compare a whole net addr from a struct sockaddr (name),
|
||||
* with that implicitly stored in an isopcb (isop).
|
||||
* The argument (which) takes values TP_LOCAL or TP_FOREIGN.
|
||||
*/
|
||||
iso_cmpnetaddr(isop, name, which)
|
||||
register struct isopcb *isop;
|
||||
register struct sockaddr_iso *name;
|
||||
int which;
|
||||
{
|
||||
struct sockaddr_iso **sisop, *backup;
|
||||
register struct sockaddr_iso *siso;
|
||||
|
||||
switch (which) {
|
||||
default:
|
||||
printf("iso_cmpnetaddr: should panic\n");
|
||||
return 0;
|
||||
case TP_LOCAL:
|
||||
sisop = &isop->isop_laddr;
|
||||
backup = &isop->isop_sladdr;
|
||||
break;
|
||||
case TP_FOREIGN:
|
||||
sisop = &isop->isop_faddr;
|
||||
backup = &isop->isop_sfaddr;
|
||||
}
|
||||
siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
|
||||
IFDEBUG(D_TPISO)
|
||||
printf("ISO_CMPNETADDR\n");
|
||||
dump_isoaddr(siso);
|
||||
ENDDEBUG
|
||||
if (name->siso_tlen && bcmp(TSEL(name), TSEL(siso), name->siso_tlen))
|
||||
return (0);
|
||||
return (bcmp((caddr_t)name->siso_data,
|
||||
(caddr_t)siso->siso_data, name->siso_nlen) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Copy a whole net addr from an isopcb (isop) into
|
||||
* a struct sockaddr (name).
|
||||
* The argument (which) takes values TP_LOCAL or TP_FOREIGN.
|
||||
*/
|
||||
|
||||
void
|
||||
iso_getnetaddr( isop, name, which)
|
||||
struct isopcb *isop;
|
||||
struct mbuf *name;
|
||||
int which;
|
||||
{
|
||||
struct sockaddr_iso *siso =
|
||||
(which == TP_LOCAL ? isop->isop_laddr : isop->isop_faddr);
|
||||
if (siso)
|
||||
bcopy((caddr_t)siso, mtod(name, caddr_t),
|
||||
(unsigned)(name->m_len = siso->siso_len));
|
||||
else
|
||||
name->m_len = 0;
|
||||
}
|
||||
/*
|
||||
* NAME: tpclnp_mtu()
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
* Sets tp_routep pointer in pcb.
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
tpclnp_mtu(tpcb)
|
||||
register struct tp_pcb *tpcb;
|
||||
{
|
||||
struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
|
||||
|
||||
IFDEBUG(D_CONN)
|
||||
printf("tpclnp_mtu(tpcb)\n", tpcb);
|
||||
ENDDEBUG
|
||||
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));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_emit()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
int
|
||||
tpclnp_output(isop, m0, datalen, nochksum)
|
||||
struct isopcb *isop;
|
||||
struct mbuf *m0;
|
||||
int datalen;
|
||||
int nochksum;
|
||||
{
|
||||
register struct mbuf *m = m0;
|
||||
IncStat(ts_tpdu_sent);
|
||||
|
||||
IFDEBUG(D_TPISO)
|
||||
struct tpdu *hdr = mtod(m0, struct tpdu *);
|
||||
|
||||
printf(
|
||||
"abt to call clnp_output: datalen 0x%x, hdr.li 0x%x, hdr.dutype 0x%x nocsum x%x dst addr:\n",
|
||||
datalen,
|
||||
(int)hdr->tpdu_li, (int)hdr->tpdu_type, nochksum);
|
||||
dump_isoaddr(isop->isop_faddr);
|
||||
printf("\nsrc addr:\n");
|
||||
dump_isoaddr(isop->isop_laddr);
|
||||
dump_mbuf(m0, "at tpclnp_output");
|
||||
ENDDEBUG
|
||||
|
||||
return
|
||||
clnp_output(m0, isop, datalen, /* flags */nochksum ? CLNP_NO_CKSUM : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_error_emit()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* This is a copy of tpclnp_output that takes the addresses
|
||||
* instead of a pcb. It's used by the tp_error_emit, when we
|
||||
* don't have an iso_pcb with which to call the normal output rtn.
|
||||
* RETURN VALUE:
|
||||
* ENOBUFS or
|
||||
* whatever (E*) is returned form the net layer output routine.
|
||||
*/
|
||||
|
||||
int
|
||||
tpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum)
|
||||
struct iso_addr *laddr, *faddr;
|
||||
struct mbuf *m0;
|
||||
int datalen;
|
||||
struct route *ro;
|
||||
int nochksum;
|
||||
{
|
||||
struct isopcb tmppcb;
|
||||
int err;
|
||||
int flags;
|
||||
register struct mbuf *m = m0;
|
||||
|
||||
IFDEBUG(D_TPISO)
|
||||
printf("tpclnp_output_dg datalen 0x%x m0 0x%x\n", datalen, m0);
|
||||
ENDDEBUG
|
||||
|
||||
/*
|
||||
* Fill in minimal portion of isopcb so that clnp can send the
|
||||
* packet.
|
||||
*/
|
||||
bzero((caddr_t)&tmppcb, sizeof(tmppcb));
|
||||
tmppcb.isop_laddr = &tmppcb.isop_sladdr;
|
||||
tmppcb.isop_laddr->siso_addr = *laddr;
|
||||
tmppcb.isop_faddr = &tmppcb.isop_sfaddr;
|
||||
tmppcb.isop_faddr->siso_addr = *faddr;
|
||||
|
||||
IFDEBUG(D_TPISO)
|
||||
printf("tpclnp_output_dg faddr: \n");
|
||||
dump_isoaddr(&tmppcb.isop_sfaddr);
|
||||
printf("\ntpclnp_output_dg laddr: \n");
|
||||
dump_isoaddr(&tmppcb.isop_sladdr);
|
||||
printf("\n");
|
||||
ENDDEBUG
|
||||
|
||||
/*
|
||||
* Do not use packet cache since this is a one shot error packet
|
||||
*/
|
||||
flags = (CLNP_NOCACHE|(nochksum?CLNP_NO_CKSUM:0));
|
||||
|
||||
IncStat(ts_tpdu_sent);
|
||||
|
||||
err = clnp_output(m0, &tmppcb, datalen, flags);
|
||||
|
||||
/*
|
||||
* Free route allocated by clnp (if the route was indeed allocated)
|
||||
*/
|
||||
if (tmppcb.isop_route.ro_rt)
|
||||
RTFREE(tmppcb.isop_route.ro_rt);
|
||||
|
||||
return(err);
|
||||
}
|
||||
/*
|
||||
* 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 give it to tp
|
||||
* No return value.
|
||||
*/
|
||||
ProtoHook
|
||||
tpclnp_input(m, src, dst, clnp_len, ce_bit)
|
||||
register struct mbuf *m;
|
||||
struct sockaddr_iso *src, *dst;
|
||||
int clnp_len, ce_bit;
|
||||
{
|
||||
struct mbuf *tp_inputprep();
|
||||
int tp_input(), cltp_input(), (*input)() = tp_input;
|
||||
|
||||
IncStat(ts_pkt_rcvd);
|
||||
|
||||
IFDEBUG(D_TPINPUT)
|
||||
printf("tpclnp_input: m 0x%x clnp_len 0x%x\n", m, clnp_len);
|
||||
dump_mbuf(m, "at tpclnp_input");
|
||||
ENDDEBUG
|
||||
/*
|
||||
* CLNP gives us an mbuf chain WITH the clnp header pulled up,
|
||||
* and the length of the clnp header.
|
||||
* 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:
|
||||
return (tuba_tcpinput(m, src, dst));
|
||||
#endif
|
||||
case 0:
|
||||
if (m->m_len == 0 && (m = m_pullup(m, 1)) == 0)
|
||||
return 0;
|
||||
if (*(mtod(m, u_char *)) == ISO10747_IDRP)
|
||||
return (idrp_input(m, src, dst));
|
||||
}
|
||||
m = tp_inputprep(m);
|
||||
if (m == 0)
|
||||
return 0;
|
||||
if (mtod(m, u_char *)[1] == UD_TPDU_type)
|
||||
input = cltp_input;
|
||||
|
||||
IFDEBUG(D_TPINPUT)
|
||||
dump_mbuf(m, "after tpclnp_input both pullups");
|
||||
ENDDEBUG
|
||||
|
||||
IFDEBUG(D_TPISO)
|
||||
printf("calling %sinput : src 0x%x, dst 0x%x, src addr:\n",
|
||||
(input == tp_input ? "tp_" : "clts_"), src, dst);
|
||||
dump_isoaddr(src);
|
||||
printf(" dst addr:\n");
|
||||
dump_isoaddr(dst);
|
||||
ENDDEBUG
|
||||
|
||||
(void) (*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) {
|
||||
tpclnp_ctlinput(PRC_QUENCH, &src);
|
||||
} else {
|
||||
tpclnp_ctlinput(PRC_QUENCH2, &src);
|
||||
}
|
||||
}
|
||||
}
|
||||
ENDDEBUG
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ProtoHook
|
||||
iso_rtchange()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tpclnp_ctlinput()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* find the tpcb pointer and pass it to tp_quench
|
||||
*/
|
||||
void
|
||||
tpiso_decbit(isop)
|
||||
struct isopcb *isop;
|
||||
{
|
||||
tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH2);
|
||||
}
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tpclnp_ctlinput()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* find the tpcb pointer and pass it to tp_quench
|
||||
*/
|
||||
void
|
||||
tpiso_quench(isop)
|
||||
struct isopcb *isop;
|
||||
{
|
||||
tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH);
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* The network layer through the protosw table.
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* When clnp an ICMP-like msg this gets called.
|
||||
* It either returns an error status to the user or
|
||||
* it causes all connections on this address to be aborted
|
||||
* by calling the appropriate xx_notify() routine.
|
||||
* (cmd) is the type of ICMP error.
|
||||
* (siso) is the address of the guy who sent the ER CLNPDU
|
||||
*/
|
||||
ProtoHook
|
||||
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();
|
||||
|
||||
IFDEBUG(D_TPINPUT)
|
||||
printf("tpclnp_ctlinput1: cmd 0x%x addr: \n", cmd);
|
||||
dump_isoaddr(siso);
|
||||
ENDDEBUG
|
||||
|
||||
if (cmd < 0 || cmd > PRC_NCMDS)
|
||||
return 0;
|
||||
if (siso->siso_family != AF_ISO)
|
||||
return 0;
|
||||
switch (cmd) {
|
||||
|
||||
case PRC_QUENCH2:
|
||||
iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_decbit);
|
||||
break;
|
||||
|
||||
case PRC_QUENCH:
|
||||
iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_quench);
|
||||
break;
|
||||
|
||||
case PRC_TIMXCEED_REASS:
|
||||
case PRC_ROUTEDEAD:
|
||||
iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_reset);
|
||||
break;
|
||||
|
||||
case PRC_HOSTUNREACH:
|
||||
case PRC_UNREACH_NET:
|
||||
case PRC_IFDOWN:
|
||||
case PRC_HOSTDEAD:
|
||||
iso_pcbnotify(&tp_isopcb, siso,
|
||||
(int)inetctlerrmap[cmd], iso_rtchange);
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
case PRC_MSGSIZE:
|
||||
case PRC_UNREACH_HOST:
|
||||
case PRC_UNREACH_PROTOCOL:
|
||||
case PRC_UNREACH_PORT:
|
||||
case PRC_UNREACH_NEEDFRAG:
|
||||
case PRC_UNREACH_SRCFAIL:
|
||||
case PRC_REDIRECT_NET:
|
||||
case PRC_REDIRECT_HOST:
|
||||
case PRC_REDIRECT_TOSNET:
|
||||
case PRC_REDIRECT_TOSHOST:
|
||||
case PRC_TIMXCEED_INTRANS:
|
||||
case PRC_PARAMPROB:
|
||||
*/
|
||||
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
|
||||
* than a sockaddr_iso.
|
||||
*/
|
||||
|
||||
static struct sockaddr_iso siso = {sizeof(siso), AF_ISO};
|
||||
tpclnp_ctlinput1(cmd, isoa)
|
||||
int cmd;
|
||||
struct iso_addr *isoa;
|
||||
{
|
||||
bzero((caddr_t)&siso.siso_addr, sizeof(siso.siso_addr));
|
||||
bcopy((caddr_t)isoa, (caddr_t)&siso.siso_addr, isoa->isoa_len);
|
||||
tpclnp_ctlinput(cmd, &siso);
|
||||
}
|
||||
|
||||
/*
|
||||
* These next 2 routines are
|
||||
* CALLED FROM:
|
||||
* xxx_notify() from tp_ctlinput() when
|
||||
* net level gets some ICMP-equiv. type event.
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Cause the connection to be aborted with some sort of error
|
||||
* reason indicating that the network layer caused the abort.
|
||||
* Fakes an ER TPDU so we can go through the driver.
|
||||
* abort always aborts the TP connection.
|
||||
* reset may or may not, depending on the TP class that's in use.
|
||||
*/
|
||||
ProtoHook
|
||||
tpiso_abort(isop)
|
||||
struct isopcb *isop;
|
||||
{
|
||||
struct tp_event e;
|
||||
|
||||
IFDEBUG(D_CONN)
|
||||
printf("tpiso_abort 0x%x\n", isop);
|
||||
ENDDEBUG
|
||||
e.ev_number = ER_TPDU;
|
||||
e.ATTR(ER_TPDU).e_reason = ECONNABORTED;
|
||||
return tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e);
|
||||
}
|
||||
|
||||
ProtoHook
|
||||
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_pcb, &e);
|
||||
|
||||
}
|
||||
|
||||
#endif /* ISO */
|
||||
@@ -1,128 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_meas.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_meas.c,v 1.2 1994/08/02 07:51:15 davidg Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_meas.c,v 1.2 1994/08/02 07:51:15 davidg Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_meas.c,v $
|
||||
*
|
||||
* tp_meas.c : create a performance measurement event
|
||||
* in the circular buffer tp_Meas[]
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_meas.h>
|
||||
|
||||
extern struct timeval time;
|
||||
|
||||
#ifdef TP_PERF_MEAS
|
||||
int tp_Measn = 0;
|
||||
struct tp_Meas tp_Meas[TPMEASN];
|
||||
|
||||
/*
|
||||
* NAME: tpmeas()
|
||||
*
|
||||
* CALLED FROM: tp_emit(), tp_soisdisconecting(), tp_soisdisconnected()
|
||||
* tp0_stash(), tp_stash(), tp_send(), tp_goodack(), tp_usrreq()
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* stashes a performance-measurement event for the given reference (ref)
|
||||
* (kind) tells which kind of event, timev is the time to be stored
|
||||
* with this event, (seq), (win), and (size) are integers that usually
|
||||
* refer to the sequence number, window number (on send) and
|
||||
* size of tpdu or window.
|
||||
*
|
||||
* RETURNS: Nada
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
void
|
||||
Tpmeas(ref, kind, timev, seq, win, size)
|
||||
u_int ref;
|
||||
u_int kind;
|
||||
struct timeval *timev;
|
||||
u_int seq, win, size;
|
||||
{
|
||||
register struct tp_Meas *tpm;
|
||||
static int mseq;
|
||||
|
||||
tpm = &tp_Meas[tp_Measn++];
|
||||
tp_Measn %= TPMEASN;
|
||||
|
||||
tpm->tpm_kind = kind;
|
||||
tpm->tpm_tseq = mseq++;
|
||||
tpm->tpm_ref = ref;
|
||||
if(kind == TPtime_from_ll)
|
||||
bcopy((caddr_t)timev, (caddr_t)&tpm->tpm_time, sizeof(struct timeval));
|
||||
else
|
||||
bcopy( (caddr_t)&time,
|
||||
(caddr_t)&tpm->tpm_time, sizeof(struct timeval) );
|
||||
tpm->tpm_seq = seq;
|
||||
tpm->tpm_window = win;
|
||||
tpm->tpm_size = size;
|
||||
}
|
||||
|
||||
#endif /* TP_PERF_MEAS */
|
||||
@@ -1,99 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_meas.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_meas.h,v 1.3 1994/08/21 06:14:25 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_MEAS_H_
|
||||
#define _NETISO_TP_MEAS_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
#ifdef TP_PERF_MEAS
|
||||
#define tpmeas(a, b, t, c, d, e) \
|
||||
Tpmeas((u_int)(a), (u_int)(b), t, (u_int)(c), (u_int)(d), (u_int)(e))
|
||||
|
||||
struct tp_Meas {
|
||||
int tpm_tseq;
|
||||
u_char tpm_kind;
|
||||
u_short tpm_ref;
|
||||
u_short tpm_size;
|
||||
u_short tpm_window;
|
||||
u_int tpm_seq;
|
||||
struct timeval tpm_time;
|
||||
};
|
||||
|
||||
#define TPMEASN 4000
|
||||
extern int tp_Measn;
|
||||
extern struct tp_Meas tp_Meas[];
|
||||
|
||||
/*
|
||||
* the kinds of events for packet tracing are:
|
||||
*/
|
||||
#define TPtime_from_session 0x01
|
||||
#define TPtime_to_session 0x02
|
||||
#define TPtime_ack_rcvd 0x03
|
||||
#define TPtime_ack_sent 0x04
|
||||
#define TPtime_from_ll 0x05
|
||||
#define TPtime_to_ll 0x06
|
||||
#define TPsbsend 0x07
|
||||
#define TPtime_open 0x08
|
||||
#define TPtime_open_X 0x28 /* xtd format */
|
||||
#define TPtime_close 0x09
|
||||
|
||||
#endif /* TP_PERF_MEAS */
|
||||
#endif
|
||||
@@ -1,714 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_output.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_output.c,v 1.3 1995/04/26 21:32:37 pst Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_output.c,v 1.3 1995/04/26 21:32:37 pst Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_output.c,v $
|
||||
*
|
||||
* In here is tp_ctloutput(), the guy called by [sg]etsockopt(),
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <netiso/tp_param.h>
|
||||
#include <netiso/tp_user.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_ip.h>
|
||||
#include <netiso/tp_clnp.h>
|
||||
#include <netiso/tp_timer.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_pcb.h>
|
||||
#include <netiso/tp_trace.h>
|
||||
|
||||
#define TPDUSIZESHIFT 24
|
||||
#define CLASSHIFT 16
|
||||
|
||||
/*
|
||||
* NAME: tp_consistency()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* tp_ctloutput(), tp_input()
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Checks the consistency of options and tpdusize with class,
|
||||
* using the parameters passed in via (param).
|
||||
* (cmd) may be TP_STRICT or TP_FORCE or both.
|
||||
* Force means it will set all the values in (tpcb) to those in
|
||||
* the input arguements iff no errors were encountered.
|
||||
* Strict means that no inconsistency will be tolerated. If it's
|
||||
* not used, checksum and tpdusize inconsistencies will be tolerated.
|
||||
* The reason for this is that in some cases, when we're negotiating down
|
||||
* from class 4, these options should be changed but should not
|
||||
* cause negotiation to fail.
|
||||
*
|
||||
* RETURNS
|
||||
* E* or EOK
|
||||
* E* if the various parms aren't ok for a given class
|
||||
* EOK if they are ok for a given class
|
||||
*/
|
||||
|
||||
int
|
||||
tp_consistency( tpcb, cmd, param )
|
||||
u_int cmd;
|
||||
struct tp_conn_param *param;
|
||||
struct tp_pcb *tpcb;
|
||||
{
|
||||
register int error = EOK;
|
||||
int class_to_use = tp_mask_to_num(param->p_class);
|
||||
|
||||
IFTRACE(D_SETPARAMS)
|
||||
tptrace(TPPTmisc,
|
||||
"tp_consist enter class_to_use dontchange param.class cmd",
|
||||
class_to_use, param->p_dont_change_params, param->p_class, cmd);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_SETPARAMS)
|
||||
printf("tp_consistency %s %s\n",
|
||||
cmd& TP_FORCE? "TP_FORCE": "",
|
||||
cmd& TP_STRICT? "TP_STRICT":"");
|
||||
ENDDEBUG
|
||||
if ((cmd & TP_FORCE) && (param->p_dont_change_params)) {
|
||||
cmd &= ~TP_FORCE;
|
||||
}
|
||||
/* can switch net services within a domain, but
|
||||
* cannot switch domains
|
||||
*/
|
||||
switch( param->p_netservice) {
|
||||
case ISO_CONS:
|
||||
case ISO_CLNS:
|
||||
case ISO_COSNS:
|
||||
/* param->p_netservice in ISO DOMAIN */
|
||||
if(tpcb->tp_domain != AF_ISO ) {
|
||||
error = EINVAL; goto done;
|
||||
}
|
||||
break;
|
||||
case IN_CLNS:
|
||||
/* param->p_netservice in INET DOMAIN */
|
||||
if( tpcb->tp_domain != AF_INET ) {
|
||||
error = EINVAL; goto done;
|
||||
}
|
||||
break;
|
||||
/* no others not possible-> netservice is a 2-bit field! */
|
||||
}
|
||||
|
||||
IFDEBUG(D_SETPARAMS)
|
||||
printf("p_class 0x%x, class_to_use 0x%x\n", param->p_class,
|
||||
class_to_use);
|
||||
ENDDEBUG
|
||||
if((param->p_netservice < 0) || (param->p_netservice > TP_MAX_NETSERVICES)){
|
||||
error = EINVAL; goto done;
|
||||
}
|
||||
if( (param->p_class & TP_CLASSES_IMPLEMENTED) == 0 ) {
|
||||
error = EINVAL; goto done;
|
||||
}
|
||||
IFDEBUG(D_SETPARAMS)
|
||||
printf("Nretrans 0x%x\n", param->p_Nretrans );
|
||||
ENDDEBUG
|
||||
if( ( param->p_Nretrans < 1 ) ||
|
||||
(param->p_cr_ticks < 1) || (param->p_cc_ticks < 1) ) {
|
||||
/* bad for any class because negot has to be done a la class 4 */
|
||||
error = EINVAL; goto done;
|
||||
}
|
||||
IFDEBUG(D_SETPARAMS)
|
||||
printf("use_csum 0x%x\n", param->p_use_checksum );
|
||||
printf("xtd_format 0x%x\n", param->p_xtd_format );
|
||||
printf("xpd_service 0x%x\n", param->p_xpd_service );
|
||||
printf("tpdusize 0x%x\n", param->p_tpdusize );
|
||||
printf("tpcb->flags 0x%x\n", tpcb->tp_flags );
|
||||
ENDDEBUG
|
||||
switch( class_to_use ) {
|
||||
|
||||
case 0:
|
||||
/* do not use checksums, xtd format, or XPD */
|
||||
|
||||
if( param->p_use_checksum | param->p_xtd_format | param->p_xpd_service ) {
|
||||
if(cmd & TP_STRICT) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
param->p_use_checksum = 0;
|
||||
param->p_xtd_format = 0;
|
||||
param->p_xpd_service = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (param->p_tpdusize < TP_MIN_TPDUSIZE) {
|
||||
if(cmd & TP_STRICT) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
param->p_tpdusize = TP_MIN_TPDUSIZE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (param->p_tpdusize > TP0_TPDUSIZE) {
|
||||
if (cmd & TP_STRICT) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
param->p_tpdusize = TP0_TPDUSIZE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* connect/disc data not allowed for class 0 */
|
||||
if (tpcb->tp_ucddata) {
|
||||
if(cmd & TP_STRICT) {
|
||||
error = EINVAL;
|
||||
} else if(cmd & TP_FORCE) {
|
||||
m_freem(tpcb->tp_ucddata);
|
||||
tpcb->tp_ucddata = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
IFDEBUG(D_SETPARAMS)
|
||||
printf("dt_ticks 0x%x\n", param->p_dt_ticks );
|
||||
printf("x_ticks 0x%x\n", param->p_x_ticks );
|
||||
printf("dr_ticks 0x%x\n", param->p_dr_ticks );
|
||||
printf("keepalive 0x%x\n", param->p_keepalive_ticks );
|
||||
printf("sendack 0x%x\n", param->p_sendack_ticks );
|
||||
printf("inact 0x%x\n", param->p_inact_ticks );
|
||||
printf("ref 0x%x\n", param->p_ref_ticks );
|
||||
ENDDEBUG
|
||||
if( (param->p_class & TP_CLASS_4 ) && (
|
||||
(param->p_dt_ticks < 1) || (param->p_dr_ticks < 1) ||
|
||||
(param->p_x_ticks < 1) || (param->p_keepalive_ticks < 1) ||
|
||||
(param->p_sendack_ticks < 1) || (param->p_ref_ticks < 1) ||
|
||||
(param->p_inact_ticks < 1) ) ) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
IFDEBUG(D_SETPARAMS)
|
||||
printf("rx_strat 0x%x\n", param->p_rx_strat );
|
||||
ENDDEBUG
|
||||
if(param->p_rx_strat >
|
||||
( TPRX_USE_CW | TPRX_EACH | TPRX_FASTSTART) ) {
|
||||
if(cmd & TP_STRICT) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
param->p_rx_strat = TPRX_USE_CW;
|
||||
}
|
||||
break;
|
||||
}
|
||||
IFDEBUG(D_SETPARAMS)
|
||||
printf("ack_strat 0x%x\n", param->p_ack_strat );
|
||||
ENDDEBUG
|
||||
if((param->p_ack_strat != 0) && (param->p_ack_strat != 1)) {
|
||||
if(cmd & TP_STRICT) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
param->p_ack_strat = TPACK_WINDOW;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (param->p_tpdusize < TP_MIN_TPDUSIZE) {
|
||||
if(cmd & TP_STRICT) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
param->p_tpdusize = TP_MIN_TPDUSIZE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (param->p_tpdusize > TP_TPDUSIZE) {
|
||||
if(cmd & TP_STRICT) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
param->p_tpdusize = TP_TPDUSIZE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ((error==0) && (cmd & TP_FORCE)) {
|
||||
long dusize = ((long)param->p_ptpdusize) << 7;
|
||||
/* Enforce Negotation rules below */
|
||||
tpcb->tp_class = param->p_class;
|
||||
if (tpcb->tp_use_checksum || param->p_use_checksum)
|
||||
tpcb->tp_use_checksum = 1;
|
||||
if (!tpcb->tp_xpd_service || !param->p_xpd_service)
|
||||
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)
|
||||
tptrace(TPPTmisc, "tp_consist returns class xtdfmt cmd",
|
||||
error, tpcb->tp_class, tpcb->tp_xtd_format, cmd);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_CONN)
|
||||
printf(
|
||||
"tp_consist rtns 0x%x class 0x%x xtd_fmt 0x%x cmd 0x%x\n",
|
||||
error, tpcb->tp_class, tpcb->tp_xtd_format, cmd);
|
||||
ENDDEBUG
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: tp_ctloutput()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* [sg]etsockopt(), via so[sg]etopt().
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Implements the socket options at transport level.
|
||||
* (cmd) is either PRCO_SETOPT or PRCO_GETOPT (see ../sys/protosw.h).
|
||||
* (so) is the socket.
|
||||
* (level) is SOL_TRANSPORT (see ../sys/socket.h)
|
||||
* (optname) is the particular command or option to be set.
|
||||
* (**mp) is an mbuf structure.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
* ENOTSOCK if the socket hasn't got an associated tpcb
|
||||
* EINVAL if
|
||||
* trying to set window too big
|
||||
* trying to set illegal max tpdu size
|
||||
* trying to set illegal credit fraction
|
||||
* trying to use unknown or unimplemented class of TP
|
||||
* structure passed to set timer values is wrong size
|
||||
* illegal combination of command/GET-SET option,
|
||||
* e.g., GET w/ TPOPT_CDDATA_CLEAR:
|
||||
* EOPNOTSUPP if the level isn't transport, or command is neither GET nor SET
|
||||
* or if the transport-specific command is not implemented
|
||||
* EISCONN if trying a command that isn't allowed after a connection
|
||||
* is established
|
||||
* ENOTCONN if trying a command that is allowed only if a connection is
|
||||
* established
|
||||
* EMSGSIZE if trying to give too much data on connect/disconnect
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
ProtoHook
|
||||
tp_ctloutput(cmd, so, level, optname, mp)
|
||||
int cmd, level, optname;
|
||||
struct socket *so;
|
||||
struct mbuf **mp;
|
||||
{
|
||||
struct tp_pcb *tpcb = sototpcb(so);
|
||||
int s = splnet();
|
||||
caddr_t value;
|
||||
unsigned val_len;
|
||||
int error = 0;
|
||||
|
||||
IFTRACE(D_REQUEST)
|
||||
tptrace(TPPTmisc, "tp_ctloutput cmd so optname mp",
|
||||
cmd, so, optname, mp);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf(
|
||||
"tp_ctloutput so 0x%x cmd 0x%x optname 0x%x, mp 0x%x *mp 0x%x tpcb 0x%x\n",
|
||||
so, cmd, optname, mp, mp?*mp:0, tpcb);
|
||||
ENDDEBUG
|
||||
if( tpcb == (struct tp_pcb *)0 ) {
|
||||
error = ENOTSOCK; goto done;
|
||||
}
|
||||
if(*mp == MNULL) {
|
||||
register struct mbuf *m;
|
||||
|
||||
MGET(m, M_DONTWAIT, TPMT_SONAME); /* does off, type, next */
|
||||
if (m == NULL) {
|
||||
splx(s);
|
||||
return ENOBUFS;
|
||||
}
|
||||
m->m_len = 0;
|
||||
m->m_act = 0;
|
||||
*mp = m;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook so one can set network options via a tp socket.
|
||||
*/
|
||||
if ( level == SOL_NETWORK ) {
|
||||
if ((tpcb->tp_nlproto == NULL) || (tpcb->tp_npcb == NULL))
|
||||
error = ENOTSOCK;
|
||||
else if (tpcb->tp_nlproto->nlp_ctloutput == NULL)
|
||||
error = EOPNOTSUPP;
|
||||
else
|
||||
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;
|
||||
}
|
||||
if (cmd != PRCO_GETOPT && cmd != PRCO_SETOPT) {
|
||||
error = EOPNOTSUPP; goto done;
|
||||
}
|
||||
if ( so->so_error ) {
|
||||
error = so->so_error; goto done;
|
||||
}
|
||||
|
||||
/* The only options allowed after connection is established
|
||||
* are GET (anything) and SET DISC DATA and SET PERF MEAS
|
||||
*/
|
||||
if ( ((so->so_state & SS_ISCONNECTING)||(so->so_state & SS_ISCONNECTED))
|
||||
&&
|
||||
(cmd == PRCO_SETOPT &&
|
||||
optname != TPOPT_DISC_DATA &&
|
||||
optname != TPOPT_CFRM_DATA &&
|
||||
optname != TPOPT_PERF_MEAS &&
|
||||
optname != TPOPT_CDDATA_CLEAR ) ) {
|
||||
error = EISCONN; goto done;
|
||||
}
|
||||
/* The only options allowed after disconnection are GET DISC DATA,
|
||||
* and TPOPT_PSTATISTICS
|
||||
* and they're not allowed if the ref timer has gone off, because
|
||||
* the tpcb is gone
|
||||
*/
|
||||
if ((so->so_state & (SS_ISCONNECTED | SS_ISCONFIRMING)) == 0) {
|
||||
if ( so->so_pcb == (caddr_t)0 ) {
|
||||
error = ENOTCONN; goto done;
|
||||
}
|
||||
if ( (tpcb->tp_state == TP_REFWAIT || tpcb->tp_state == TP_CLOSING) &&
|
||||
(optname != TPOPT_DISC_DATA && optname != TPOPT_PSTATISTICS)) {
|
||||
error = ENOTCONN; goto done;
|
||||
}
|
||||
}
|
||||
|
||||
value = mtod(*mp, caddr_t); /* it's aligned, don't worry,
|
||||
* but lint complains about it
|
||||
*/
|
||||
val_len = (*mp)->m_len;
|
||||
|
||||
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;
|
||||
} 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;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
case TPOPT_MY_TSEL:
|
||||
if ( cmd == PRCO_GETOPT ) {
|
||||
ASSERT( tpcb->tp_lsuffixlen <= MAX_TSAP_SEL_LEN );
|
||||
bcopy((caddr_t)tpcb->tp_lsuffix, value, tpcb->tp_lsuffixlen);
|
||||
(*mp)->m_len = tpcb->tp_lsuffixlen;
|
||||
} else /* cmd == PRCO_SETOPT */ {
|
||||
if( (val_len > MAX_TSAP_SEL_LEN) || (val_len <= 0 )) {
|
||||
printf("val_len 0x%x (*mp)->m_len 0x%x\n", val_len, (*mp));
|
||||
error = EINVAL;
|
||||
} else {
|
||||
bcopy(value, (caddr_t)tpcb->tp_lsuffix, val_len);
|
||||
tpcb->tp_lsuffixlen = val_len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TPOPT_PEER_TSEL:
|
||||
if ( cmd == PRCO_GETOPT ) {
|
||||
ASSERT( tpcb->tp_fsuffixlen <= MAX_TSAP_SEL_LEN );
|
||||
bcopy((caddr_t)tpcb->tp_fsuffix, value, tpcb->tp_fsuffixlen);
|
||||
(*mp)->m_len = tpcb->tp_fsuffixlen;
|
||||
} else /* cmd == PRCO_SETOPT */ {
|
||||
if( (val_len > MAX_TSAP_SEL_LEN) || (val_len <= 0 )) {
|
||||
printf("val_len 0x%x (*mp)->m_len 0x%x\n", val_len, (*mp));
|
||||
error = EINVAL;
|
||||
} else {
|
||||
bcopy(value, (caddr_t)tpcb->tp_fsuffix, val_len);
|
||||
tpcb->tp_fsuffixlen = val_len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TPOPT_FLAGS:
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("%s TPOPT_FLAGS value 0x%x *value 0x%x, flags 0x%x \n",
|
||||
cmd==PRCO_GETOPT?"GET":"SET",
|
||||
value,
|
||||
*value,
|
||||
tpcb->tp_flags);
|
||||
ENDDEBUG
|
||||
|
||||
if ( cmd == PRCO_GETOPT ) {
|
||||
*(int *)value = (int)tpcb->tp_flags;
|
||||
(*mp)->m_len = sizeof(u_int);
|
||||
} else /* cmd == PRCO_SETOPT */ {
|
||||
error = EINVAL; goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
case TPOPT_PARAMS:
|
||||
/* This handles:
|
||||
* timer values,
|
||||
* class, use of transport expedited data,
|
||||
* max tpdu size, checksum, xtd format and
|
||||
* disconnect indications, and may get rid of connect/disc data
|
||||
*/
|
||||
IFDEBUG(D_SETPARAMS)
|
||||
printf("TPOPT_PARAMS value 0x%x, cmd %s \n", value,
|
||||
cmd==PRCO_GETOPT?"GET":"SET");
|
||||
ENDDEBUG
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("TPOPT_PARAMS value 0x%x, cmd %s \n", value,
|
||||
cmd==PRCO_GETOPT?"GET":"SET");
|
||||
ENDDEBUG
|
||||
|
||||
if ( cmd == PRCO_GETOPT ) {
|
||||
*(struct tp_conn_param *)value = tpcb->_tp_param;
|
||||
(*mp)->m_len = sizeof(tpcb->_tp_param);
|
||||
} else /* cmd == PRCO_SETOPT */ {
|
||||
if( (error =
|
||||
tp_consistency(tpcb, TP_STRICT | TP_FORCE,
|
||||
(struct tp_conn_param *)value))==0) {
|
||||
/*
|
||||
* tp_consistency doesn't copy the whole set of params
|
||||
*/
|
||||
tpcb->_tp_param = *(struct tp_conn_param *)value;
|
||||
(*mp)->m_len = sizeof(tpcb->_tp_param);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TPOPT_PSTATISTICS:
|
||||
#ifdef TP_PERF_MEAS
|
||||
if (cmd == PRCO_SETOPT) {
|
||||
error = EINVAL; goto done;
|
||||
}
|
||||
IFPERF(tpcb)
|
||||
if (*mp) {
|
||||
struct mbuf * n;
|
||||
do {
|
||||
MFREE(*mp, n);
|
||||
*mp = n;
|
||||
} while (n);
|
||||
}
|
||||
*mp = m_copym(tpcb->tp_p_mbuf, (int)M_COPYALL, M_WAITOK);
|
||||
ENDPERF
|
||||
else {
|
||||
error = EINVAL; goto done;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
error = EOPNOTSUPP;
|
||||
goto done;
|
||||
#endif /* TP_PERF_MEAS */
|
||||
|
||||
case TPOPT_CDDATA_CLEAR:
|
||||
if (cmd == PRCO_GETOPT) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
if (tpcb->tp_ucddata) {
|
||||
m_freem(tpcb->tp_ucddata);
|
||||
tpcb->tp_ucddata = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TPOPT_CFRM_DATA:
|
||||
case TPOPT_DISC_DATA:
|
||||
case TPOPT_CONN_DATA:
|
||||
if( tpcb->tp_class == TP_CLASS_0 ) {
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("%s\n", optname==TPOPT_DISC_DATA?"DISC data":"CONN data");
|
||||
printf("m_len 0x%x, vallen 0x%x so_snd.cc 0x%x\n",
|
||||
(*mp)->m_len, val_len, so->so_snd.sb_cc);
|
||||
dump_mbuf(so->so_snd.sb_mb, "tp_ctloutput: sosnd ");
|
||||
ENDDEBUG
|
||||
if (cmd == PRCO_SETOPT) {
|
||||
int len = tpcb->tp_ucddata ? tpcb->tp_ucddata->m_len : 0;
|
||||
/* can append connect data in several calls */
|
||||
if (len + val_len >
|
||||
(optname==TPOPT_CONN_DATA?TP_MAX_CR_DATA:TP_MAX_DR_DATA) ) {
|
||||
error = EMSGSIZE; goto done;
|
||||
}
|
||||
(*mp)->m_next = MNULL;
|
||||
(*mp)->m_act = 0;
|
||||
if (tpcb->tp_ucddata)
|
||||
m_cat(tpcb->tp_ucddata, *mp);
|
||||
else
|
||||
tpcb->tp_ucddata = *mp;
|
||||
IFDEBUG(D_REQUEST)
|
||||
dump_mbuf(tpcb->tp_ucddata, "tp_ctloutput after CONN_DATA");
|
||||
ENDDEBUG
|
||||
IFTRACE(D_REQUEST)
|
||||
tptrace(TPPTmisc,"C/D DATA: flags snd.sbcc val_len",
|
||||
tpcb->tp_flags, so->so_snd.sb_cc,val_len,0);
|
||||
ENDTRACE
|
||||
*mp = MNULL;
|
||||
if (optname == TPOPT_CFRM_DATA && (so->so_state & SS_ISCONFIRMING))
|
||||
(void) tp_confirm(tpcb);
|
||||
}
|
||||
break;
|
||||
|
||||
case TPOPT_PERF_MEAS:
|
||||
#ifdef TP_PERF_MEAS
|
||||
if (cmd == PRCO_GETOPT) {
|
||||
*value = (u_int)tpcb->tp_perf_on;
|
||||
(*mp)->m_len = sizeof(u_int);
|
||||
} else if (cmd == PRCO_SETOPT) {
|
||||
(*mp)->m_len = 0;
|
||||
if ((*value) != 0 && (*value) != 1 )
|
||||
error = EINVAL;
|
||||
else tpcb->tp_perf_on = (*value);
|
||||
}
|
||||
if( tpcb->tp_perf_on )
|
||||
error = tp_setup_perf(tpcb);
|
||||
#else /* TP_PERF_MEAS */
|
||||
error = EOPNOTSUPP;
|
||||
#endif /* TP_PERF_MEAS */
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EOPNOTSUPP;
|
||||
}
|
||||
|
||||
done:
|
||||
IFDEBUG(D_REQUEST)
|
||||
dump_mbuf(so->so_snd.sb_mb, "tp_ctloutput sosnd at end");
|
||||
dump_mbuf(*mp, "tp_ctloutput *mp");
|
||||
ENDDEBUG
|
||||
/*
|
||||
* sigh: getsockopt looks only at m_len : all output data must
|
||||
* reside in the first mbuf
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@@ -1,367 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_param.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_param.h,v 1.3 1994/08/21 06:14:26 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_PARAM_H_
|
||||
#define _NETISO_TP_PARAM_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_param.h,v 1.3 1994/08/21 06:14:26 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_param.h,v $
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************
|
||||
* compile time parameters that can be changed
|
||||
*****************************************************/
|
||||
|
||||
#define TP_CLASSES_IMPLEMENTED 0x11 /* zero and 4 */
|
||||
|
||||
#define TP_DECBIT_CLEAR_COUNT 3
|
||||
|
||||
/*#define N_TPREF 100 */
|
||||
#ifdef KERNEL
|
||||
extern int N_TPREF;
|
||||
#endif
|
||||
|
||||
#define TP_SOCKBUFSIZE ((u_long)4096)
|
||||
#define TP0_SOCKBUFSIZE ((u_long)512)
|
||||
#define MAX_TSAP_SEL_LEN 64
|
||||
|
||||
/* maximum tpdu size we'll accept: */
|
||||
#define TP_TPDUSIZE 0xc /* 4096 octets for classes 1-4*/
|
||||
#define TP0_TPDUSIZE 0xb /* 2048 octets for class 0 */
|
||||
#define TP_DFL_TPDUSIZE 0x7 /* 128 octets default */
|
||||
/* NOTE: don't ever negotiate 8192 because could get
|
||||
* wraparound in checksumming
|
||||
* (No mtu is likely to be larger than 4K anyway...)
|
||||
*/
|
||||
#define TP_NRETRANS 12 /* TCP_MAXRXTSHIFT + 1 */
|
||||
#define TP_MAXRXTSHIFT 6 /* factor of 64 */
|
||||
#define TP_MAXPORT 0xefff
|
||||
|
||||
/* 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
|
||||
*/
|
||||
#define T_CONN_DATA 0x1
|
||||
#define T_DISCONNECT 0x2
|
||||
#define T_DISC_DATA 0x4
|
||||
#define T_XDATA 0x8
|
||||
|
||||
#define ISO_CLNS 0
|
||||
#define IN_CLNS 1
|
||||
#define ISO_CONS 2
|
||||
#define ISO_COSNS 3
|
||||
#define TP_MAX_NETSERVICES 3
|
||||
|
||||
/* Indices into tp stats ackreason[i] */
|
||||
#define _ACK_DONT_ 0
|
||||
#define _ACK_STRAT_EACH_ 0x1
|
||||
#define _ACK_STRAT_FULLWIN_ 0x2
|
||||
#define _ACK_DUP_ 0x3
|
||||
#define _ACK_EOT_ 0x4
|
||||
#define _ACK_REORDER_ 0x5
|
||||
#define _ACK_USRRCV_ 0x6
|
||||
#define _ACK_FCC_ 0x7
|
||||
#define _ACK_NUM_REASONS_ 0x8
|
||||
|
||||
/* masks for use in tp_stash() */
|
||||
#define ACK_DONT 0
|
||||
#define ACK_STRAT_EACH (1<< _ACK_STRAT_EACH_)
|
||||
#define ACK_STRAT_FULLWIN (1<< _ACK_STRAT_FULLWIN_)
|
||||
#define ACK_DUP (1<< _ACK_DUP_)
|
||||
#define ACK_EOT (1<< _ACK_EOT_)
|
||||
#define ACK_REORDER (1<< _ACK_REORDER_)
|
||||
|
||||
/******************************************************
|
||||
* constants used in the protocol
|
||||
*****************************************************/
|
||||
|
||||
#define TP_VERSION 0x1
|
||||
|
||||
#define TP_MAX_HEADER_LEN 256
|
||||
|
||||
#define TP_MIN_TPDUSIZE 0x7 /* 128 octets */
|
||||
#define TP_MAX_TPDUSIZE 0xd /* 8192 octets */
|
||||
|
||||
#define TP_MAX_XPD_DATA 0x10 /* 16 octets */
|
||||
#define TP_MAX_CC_DATA 0x20 /* 32 octets */
|
||||
#define TP_MAX_CR_DATA TP_MAX_CC_DATA
|
||||
#define TP_MAX_DR_DATA 0x40 /* 64 octets */
|
||||
|
||||
#define TP_XTD_FMT_BIT 0x80000000
|
||||
#define TP_XTD_FMT_MASK 0x7fffffff
|
||||
#define TP_NML_FMT_BIT 0x80
|
||||
#define TP_NML_FMT_MASK 0x7f
|
||||
|
||||
/*
|
||||
* values for the tpdu_type field, 2nd byte in a tpdu
|
||||
*/
|
||||
|
||||
#define TP_MIN_TPDUTYPE 0x1
|
||||
|
||||
#define XPD_TPDU_type 0x1
|
||||
#define XAK_TPDU_type 0x2
|
||||
#define GR_TPDU_type 0x3
|
||||
#define AK_TPDU_type 0x6
|
||||
#define ER_TPDU_type 0x7
|
||||
#define DR_TPDU_type 0x8
|
||||
#define DC_TPDU_type 0xc
|
||||
#define CC_TPDU_type 0xd
|
||||
#define CR_TPDU_type 0xe
|
||||
#define DT_TPDU_type 0xf
|
||||
|
||||
#define TP_MAX_TPDUTYPE 0xf
|
||||
|
||||
/*
|
||||
* identifiers for the variable-length options in tpdus
|
||||
*/
|
||||
|
||||
#define TPP_acktime 0x85
|
||||
#define TPP_residER 0x86
|
||||
#define TPP_priority 0x87
|
||||
#define TPP_transdelay 0x88
|
||||
#define TPP_throughput 0x89
|
||||
#define TPP_subseq 0x8a
|
||||
#define TPP_flow_cntl_conf 0x8c /* not implemented */
|
||||
#define TPP_addl_info 0xe0
|
||||
#define TPP_tpdu_size 0xc0
|
||||
#define TPP_calling_sufx 0xc1
|
||||
#define TPP_invalid_tpdu 0xc1 /* the bozos used a value twice */
|
||||
#define TPP_called_sufx 0xc2
|
||||
#define TPP_checksum 0xc3
|
||||
#define TPP_vers 0xc4
|
||||
#define TPP_security 0xc5
|
||||
#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 */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* FALSE */
|
||||
|
||||
#define TP_LOCAL 22
|
||||
#define TP_FOREIGN 33
|
||||
|
||||
#ifndef EOK
|
||||
#define EOK 0
|
||||
#endif /* EOK */
|
||||
|
||||
#define TP_CLASS_0 (1<<0)
|
||||
#define TP_CLASS_1 (1<<1)
|
||||
#define TP_CLASS_2 (1<<2)
|
||||
#define TP_CLASS_3 (1<<3)
|
||||
#define TP_CLASS_4 (1<<4)
|
||||
|
||||
#define TP_FORCE 0x1
|
||||
#define TP_STRICT 0x2
|
||||
|
||||
#ifndef MNULL
|
||||
#define MNULL (struct mbuf *)0
|
||||
#endif /* MNULL */
|
||||
/* if ../sys/mbuf.h gets MT_types up to 0x40, these will
|
||||
* have to be changed:
|
||||
*/
|
||||
#define MT_XPD 0x44
|
||||
#define MT_EOT 0x40
|
||||
|
||||
#define TP_ENOREF 0x80000000
|
||||
|
||||
typedef unsigned int SeqNum;
|
||||
typedef unsigned short RefNum;
|
||||
typedef int ProtoHook;
|
||||
|
||||
/******************************************************
|
||||
* Macro used all over, for driver
|
||||
*****************************************************/
|
||||
|
||||
#define DoEvent(x) \
|
||||
((E.ev_number=(x)),(tp_driver(tpcb,&E)))
|
||||
|
||||
/******************************************************
|
||||
* Some macros used all over, for timestamping
|
||||
*****************************************************/
|
||||
|
||||
#define GET_CUR_TIME(tvalp) ((*tvalp) = time)
|
||||
|
||||
#define GET_TIME_SINCE(oldtvalp, diffp) {\
|
||||
(diffp)->tv_sec = time.tv_sec - (oldtvalp)->tv_sec;\
|
||||
(diffp)->tv_usec = time.tv_usec - (oldtvalp)->tv_usec;\
|
||||
if( (diffp)->tv_usec <0 ) {\
|
||||
(diffp)->tv_sec --;\
|
||||
(diffp)->tv_usec = 1000000 - (diffp)->tv_usec;\
|
||||
}\
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* Some macros used for address families
|
||||
*****************************************************/
|
||||
|
||||
#define satosiso(ADDR) ((struct sockaddr_iso *)(ADDR))
|
||||
#define satosin(ADDR) ((struct sockaddr_in *)(ADDR))
|
||||
|
||||
/******************************************************
|
||||
* Macro used for changing types of mbufs
|
||||
*****************************************************/
|
||||
|
||||
#define CHANGE_MTYPE(m, TYPE)\
|
||||
if((m)->m_type != TYPE) { \
|
||||
mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[TYPE]++; \
|
||||
(m)->m_type = TYPE; \
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* Macros used for adding options to a tpdu header and for
|
||||
* parsing the headers.
|
||||
* Options are variable-length and must be bcopy-d because on the
|
||||
* RT your assignments must be N-word aligned for objects of length
|
||||
* N. Such a drag.
|
||||
*****************************************************/
|
||||
|
||||
struct tp_vbp {
|
||||
u_char tpv_code;
|
||||
char tpv_len;
|
||||
char tpv_val;
|
||||
};
|
||||
#define vbptr(x) ((struct tp_vbp *)(x))
|
||||
#define vbval(x,type) (*((type *)&(((struct tp_vbp *)(x))->tpv_val)))
|
||||
#define vbcode(x) (vbptr(x)->tpv_code)
|
||||
#define vblen(x) (vbptr(x)->tpv_len)
|
||||
|
||||
#define vb_putval(dst,type,src)\
|
||||
bcopy((caddr_t)&(src),(caddr_t)&(((struct tp_vbp *)(dst))->tpv_val),\
|
||||
sizeof(type))
|
||||
|
||||
#define vb_getval(src,type,dst)\
|
||||
bcopy((caddr_t)&(((struct tp_vbp *)(src))->tpv_val),(caddr_t)&(dst),sizeof(type))
|
||||
|
||||
#define ADDOPTION(type, DU, len, src)\
|
||||
{ register caddr_t P;\
|
||||
P = (caddr_t)(DU) + (int)((DU)->tpdu_li);\
|
||||
vbptr(P)->tpv_code = type;\
|
||||
vbptr(P)->tpv_len = len;\
|
||||
bcopy((caddr_t)&src, (caddr_t)&(vbptr(P)->tpv_val), (unsigned)len);\
|
||||
DU->tpdu_li += len+2;/* 1 for code, 1 for length */\
|
||||
}
|
||||
/******************************************************
|
||||
* Macro for the local credit:
|
||||
* uses max transmission unit for the ll
|
||||
* (as modified by the max TPDU size negotiated)
|
||||
*****************************************************/
|
||||
|
||||
#if defined(ARGO_DEBUG)&&!defined(LOCAL_CREDIT_EXPAND)
|
||||
#define LOCAL_CREDIT(tpcb) tp_local_credit(tpcb)
|
||||
#else
|
||||
#define LOCAL_CREDIT(tpcb) { if (tpcb->tp_rsycnt == 0) {\
|
||||
register struct sockbuf *xxsb = &((tpcb)->tp_sock->so_rcv);\
|
||||
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 \
|
||||
(tpcb)->tp_lcredit = xxi; \
|
||||
} }
|
||||
#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 <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
|
||||
-1004
File diff suppressed because it is too large
Load Diff
@@ -1,359 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_pcb.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_pcb.h,v 1.5 1995/05/30 08:11:27 rgrimes Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_PCB_H_
|
||||
#define _NETISO_TP_PCB_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_pcb.h,v 1.5 1995/05/30 08:11:27 rgrimes Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_pcb.h,v $
|
||||
*
|
||||
*
|
||||
* 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 sblock
|
||||
#include <sys/socketvar.h>
|
||||
#endif /* sblock */
|
||||
|
||||
/* NOTE: the code depends on REF_CLOSED > REF_OPEN > the rest, and
|
||||
* on REF_FREE being zero
|
||||
*
|
||||
* Possible improvement:
|
||||
* think about merging the tp_ref w/ the tpcb and doing a search
|
||||
* through the tpcb list, from tpb. This would slow down lookup
|
||||
* during data transfer
|
||||
* It would be a little nicer also to have something based on the
|
||||
* clock (like top n bits of the reference is part of the clock, to
|
||||
* minimize the likelihood of reuse after a crash)
|
||||
* also, need to keep the timer servicing part to a minimum (although
|
||||
* the cost of this is probably independent of whether the timers are
|
||||
* in the pcb or in an array..
|
||||
* Last, would have to make the number of timers a function of the amount of
|
||||
* mbufs available, plus some for the frozen references.
|
||||
*
|
||||
* Possible improvement:
|
||||
* Might not need the ref_state stuff either...
|
||||
* REF_FREE could correspond to tp_state == CLOSED or nonexistent tpcb,
|
||||
* REF_OPEN to tp_state anywhere from AK_WAIT or CR_SENT to CLOSING
|
||||
* REF_OPENING could correspond to LISTENING, because that's the
|
||||
* way it's used, not because the correspondence is exact.
|
||||
* REF_CLOSED could correspond to REFWAIT
|
||||
*/
|
||||
#define REF_FROZEN 3 /* has ref timer only */
|
||||
#define REF_OPEN 2 /* has timers, possibly active */
|
||||
#define REF_OPENING 1 /* in use (has a pcb) but no timers */
|
||||
#define REF_FREE 0 /* free to reallocate */
|
||||
|
||||
#define TM_NTIMERS 6
|
||||
|
||||
struct tp_ref {
|
||||
struct tp_pcb *tpr_pcb; /* back ptr to PCB */
|
||||
};
|
||||
|
||||
/* 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 {
|
||||
int nlp_afamily; /* address family */
|
||||
int (*nlp_putnetaddr)(); /* puts addresses in nl pcb */
|
||||
int (*nlp_getnetaddr)(); /* gets addresses from nl pcb */
|
||||
int (*nlp_cmpnetaddr)(); /* compares address in pcb with sockaddr */
|
||||
int (*nlp_putsufx)(); /* puts transport suffixes in nl pcb */
|
||||
int (*nlp_getsufx)(); /* gets transport suffixes from nl pcb */
|
||||
int (*nlp_recycle_suffix)();/* clears suffix from nl pcb */
|
||||
int (*nlp_mtu)(); /* figures out mtu based on nl used */
|
||||
int (*nlp_pcbbind)(); /* bind to pcb for net level */
|
||||
int (*nlp_pcbconn)(); /* connect for net level */
|
||||
int (*nlp_pcbdisc)(); /* disconnect net level */
|
||||
int (*nlp_pcbdetach)(); /* detach net level pcb */
|
||||
int (*nlp_pcballoc)(); /* allocate a net level pcb */
|
||||
int (*nlp_output)(); /* prepare a packet to give to nl */
|
||||
int (*nlp_dgoutput)(); /* prepare a packet to give to nl */
|
||||
int (*nlp_ctloutput)(); /* hook for network set/get options */
|
||||
caddr_t nlp_pcblist; /* list of xx_pcb's for connections */
|
||||
};
|
||||
|
||||
|
||||
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 */
|
||||
caddr_t tp_npcb; /* to lower layer pcb */
|
||||
struct nl_protosw *tp_nlproto; /* lower-layer dependent routines */
|
||||
struct rtentry **tp_routep; /* obtain mtu; inside npcb */
|
||||
|
||||
|
||||
RefNum tp_lref; /* local reference */
|
||||
RefNum tp_fref; /* foreign reference */
|
||||
|
||||
u_int tp_seqmask; /* mask for seq space */
|
||||
u_int tp_seqbit; /* bit for seq number wraparound */
|
||||
u_int tp_seqhalf; /* half the seq space */
|
||||
|
||||
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 */
|
||||
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;
|
||||
|
||||
/* receive window as a scaled int (8 bit fraction part) */
|
||||
|
||||
struct cong_sample {
|
||||
ushort cs_size; /* current window size */
|
||||
ushort cs_received; /* PDUs received in this sample */
|
||||
ushort cs_ce_set; /* PDUs received in this sample with CE bit set */
|
||||
} tp_cong_sample;
|
||||
|
||||
|
||||
/* parameters per-connection controllable by user */
|
||||
struct tp_conn_param _tp_param;
|
||||
|
||||
#define tp_Nretrans _tp_param.p_Nretrans
|
||||
#define tp_dr_ticks _tp_param.p_dr_ticks
|
||||
#define tp_cc_ticks _tp_param.p_cc_ticks
|
||||
#define tp_dt_ticks _tp_param.p_dt_ticks
|
||||
#define tp_xpd_ticks _tp_param.p_x_ticks
|
||||
#define tp_cr_ticks _tp_param.p_cr_ticks
|
||||
#define tp_keepalive_ticks _tp_param.p_keepalive_ticks
|
||||
#define tp_sendack_ticks _tp_param.p_sendack_ticks
|
||||
#define tp_refer_ticks _tp_param.p_ref_ticks
|
||||
#define tp_inact_ticks _tp_param.p_inact_ticks
|
||||
#define tp_xtd_format _tp_param.p_xtd_format
|
||||
#define tp_xpd_service _tp_param.p_xpd_service
|
||||
#define tp_ack_strat _tp_param.p_ack_strat
|
||||
#define tp_rx_strat _tp_param.p_rx_strat
|
||||
#define tp_use_checksum _tp_param.p_use_checksum
|
||||
#define tp_use_efc _tp_param.p_use_efc
|
||||
#define tp_use_nxpd _tp_param.p_use_nxpd
|
||||
#define tp_use_rcc _tp_param.p_use_rcc
|
||||
#define tp_tpdusize _tp_param.p_tpdusize
|
||||
#define tp_class _tp_param.p_class
|
||||
#define tp_winsize _tp_param.p_winsize
|
||||
#define tp_no_disc_indications _tp_param.p_no_disc_indications
|
||||
#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;
|
||||
/* whereas tp_tpdusize is log2(the negotiated max size)
|
||||
* l_tpdusize is the size we'll use when sending, in # chars
|
||||
*/
|
||||
|
||||
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_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 */
|
||||
|
||||
/* addressing */
|
||||
u_short tp_domain; /* domain (INET, ISO) */
|
||||
/* for compatibility with the *old* way and with INET, be sure that
|
||||
* that lsuffix and fsuffix are aligned to a short addr.
|
||||
* having them follow the u_short *suffixlen should suffice (choke)
|
||||
*/
|
||||
u_short tp_fsuffixlen; /* foreign suffix */
|
||||
char tp_fsuffix[MAX_TSAP_SEL_LEN];
|
||||
u_short tp_lsuffixlen; /* local suffix */
|
||||
char tp_lsuffix[MAX_TSAP_SEL_LEN];
|
||||
#define SHORT_LSUFXP(tpcb) ((short *)((tpcb)->tp_lsuffix))
|
||||
#define SHORT_FSUFXP(tpcb) ((short *)((tpcb)->tp_fsuffix))
|
||||
|
||||
/* 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 */
|
||||
#ifdef notused
|
||||
struct sockbuf tp_Xrcv; /* for expedited data */
|
||||
#endif
|
||||
#define tp_Xrcv tp_sock->so_rcv
|
||||
SeqNum tp_Xsndnxt; /* next XPD seq # to send */
|
||||
SeqNum tp_Xuna; /* seq # of unacked XPD */
|
||||
SeqNum tp_Xrcvnxt; /* next XPD seq # expect to recv */
|
||||
|
||||
/* AK subsequencing */
|
||||
u_short tp_s_subseq; /* next subseq to send */
|
||||
u_short tp_r_subseq; /* highest recv subseq */
|
||||
|
||||
};
|
||||
|
||||
u_int tp_start_win;
|
||||
|
||||
#define ROUND(scaled_int) (((scaled_int) >> 8) + (((scaled_int) & 0x80) ? 1:0))
|
||||
|
||||
/* to round off a scaled int with an 8 bit fraction part */
|
||||
|
||||
#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;
|
||||
|
||||
#define CONG_UPDATE_SAMPLE(pcb, ce_bit) \
|
||||
pcb->tp_cong_sample.cs_received++; \
|
||||
if (ce_bit) { \
|
||||
pcb->tp_cong_sample.cs_ce_set++; \
|
||||
} \
|
||||
if (pcb->tp_cong_sample.cs_size <= pcb->tp_cong_sample.cs_received) { \
|
||||
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); \
|
||||
} \
|
||||
else { \
|
||||
pcb->tp_win_recv += (1 << 8); /* add one to the scaled int */ \
|
||||
} \
|
||||
pcb->tp_lcredit = ROUND(pcb->tp_win_recv); \
|
||||
CONG_INIT_SAMPLE(pcb); \
|
||||
}
|
||||
|
||||
#ifdef KERNEL
|
||||
extern struct tp_refinfo tp_refinfo;
|
||||
extern struct timeval time;
|
||||
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_ftimeolist;
|
||||
#endif
|
||||
|
||||
#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
|
||||
@@ -1,125 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_seq.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_seq.h,v 1.3 1994/08/21 06:14:28 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_SEQ_H_
|
||||
#define _NETISO_TP_SEQ_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_seq.h,v 1.3 1994/08/21 06:14:28 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_seq.h,v $
|
||||
*
|
||||
* 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.
|
||||
* tp_seqbit : 1 + tp_seqmask
|
||||
* tp_seqhalf : tp_seqbit / 2 or half the sequence space (rounded up)
|
||||
* Not exactly fast, but at least it's maintainable.
|
||||
*/
|
||||
|
||||
#define SEQ(tpcb,x) \
|
||||
((x) & (tpcb)->tp_seqmask)
|
||||
|
||||
#define SEQ_GT(tpcb, seq, operand ) \
|
||||
( ((int)((seq)-(operand)) > 0)\
|
||||
? ((int)((seq)-(operand)) < (int)(tpcb)->tp_seqhalf)\
|
||||
: !(-((int)(seq)-(operand)) < (int)(tpcb)->tp_seqhalf))
|
||||
|
||||
#define SEQ_GEQ(tpcb, seq, operand ) \
|
||||
( ((int)((seq)-(operand)) >= 0)\
|
||||
? ((int)((seq)-(operand)) < (int)(tpcb)->tp_seqhalf)\
|
||||
: !((-((int)(seq)-(operand))) < (int)(tpcb)->tp_seqhalf))
|
||||
|
||||
#define SEQ_LEQ(tpcb, seq, operand ) \
|
||||
( ((int)((seq)-(operand)) <= 0)\
|
||||
? ((-(int)((seq)-(operand))) < (int)(tpcb)->tp_seqhalf)\
|
||||
: !(((int)(seq)-(operand)) < (int)(tpcb)->tp_seqhalf))
|
||||
|
||||
#define SEQ_LT(tpcb, seq, operand ) \
|
||||
( ((int)((seq)-(operand)) < 0)\
|
||||
? ((-(int)((seq)-(operand))) < (int)(tpcb)->tp_seqhalf)\
|
||||
: !(((int)(seq)-(operand)) < (int)(tpcb)->tp_seqhalf))
|
||||
|
||||
#define SEQ_MIN(tpcb, a, b) ( SEQ_GT(tpcb, a, b) ? b : a)
|
||||
|
||||
#define SEQ_MAX(tpcb, a, b) ( SEQ_GT(tpcb, a, b) ? a : b)
|
||||
|
||||
#define SEQ_INC(tpcb, Seq) ((++Seq), ((Seq) &= (tpcb)->tp_seqmask))
|
||||
|
||||
#define SEQ_DEC(tpcb, Seq)\
|
||||
((Seq) = (((Seq)+(unsigned)((int)(tpcb)->tp_seqbit - 1))&(tpcb)->tp_seqmask))
|
||||
|
||||
/* (amt) had better be less than the seq bit ! */
|
||||
|
||||
#define SEQ_SUB(tpcb, Seq, amt)\
|
||||
(((Seq) + (unsigned)((int)(tpcb)->tp_seqbit - amt)) & (tpcb)->tp_seqmask)
|
||||
#define SEQ_ADD(tpcb, Seq, amt) (((Seq) + (unsigned)amt) & (tpcb)->tp_seqmask)
|
||||
|
||||
|
||||
#define IN_RWINDOW(tpcb, seq, lwe, uwe)\
|
||||
( SEQ_GEQ(tpcb, seq, lwe) && SEQ_LT(tpcb, seq, uwe) )
|
||||
|
||||
#define IN_SWINDOW(tpcb, seq, lwe, uwe)\
|
||||
( SEQ_GT(tpcb, seq, lwe) && SEQ_LEQ(tpcb, seq, uwe) )
|
||||
|
||||
#endif
|
||||
@@ -1,284 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_stat.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_stat.h,v 1.3 1994/08/21 06:14:28 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_STAT_H_
|
||||
#define _NETISO_TP_STAT_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_stat.h,v 1.3 1994/08/21 06:14:28 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_stat.h,v $
|
||||
*
|
||||
* Here are the data structures in which the global
|
||||
* statistics(counters) are gathered.
|
||||
*/
|
||||
|
||||
struct tp_stat {
|
||||
u_long ts_param_ignored;
|
||||
u_long ts_unused3;
|
||||
u_long ts_bad_csum;
|
||||
|
||||
u_long ts_inv_length;
|
||||
u_long ts_inv_pcode;
|
||||
u_long ts_inv_dutype;
|
||||
u_long ts_negotfailed;
|
||||
u_long ts_inv_dref;
|
||||
u_long ts_inv_pval;
|
||||
u_long ts_inv_sufx;
|
||||
u_long ts_inv_aclass;
|
||||
|
||||
u_long ts_xtd_fmt;
|
||||
u_long ts_use_txpd;
|
||||
u_long ts_csum_off;
|
||||
u_long ts_send_drop;
|
||||
u_long ts_recv_drop;
|
||||
|
||||
u_long ts_xpd_intheway;/* xpd mark caused data flow to stop */
|
||||
u_long ts_xpdmark_del; /* xpd markers thrown away */
|
||||
u_long ts_dt_ooo; /* dt tpdus received out of order */
|
||||
u_long ts_dt_niw; /* dt tpdus received & not in window */
|
||||
u_long ts_xpd_niw; /* xpd tpdus received & not in window */
|
||||
u_long ts_xpd_dup;
|
||||
u_long ts_dt_dup; /* dt tpdus received & are duplicates */
|
||||
|
||||
u_long ts_zfcdt; /* # times f credit went down to 0 */
|
||||
u_long ts_lcdt_reduced; /*
|
||||
# times local cdt reduced on an acknowledgement.
|
||||
*/
|
||||
|
||||
u_long ts_pkt_rcvd; /* from ip */
|
||||
u_long ts_tpdu_rcvd; /* accepted as a TPDU in tp_input */
|
||||
u_long ts_tpdu_sent;
|
||||
u_long ts_unused2;
|
||||
|
||||
u_long ts_retrans_cr;
|
||||
u_long ts_retrans_cc;
|
||||
u_long ts_retrans_dr;
|
||||
u_long ts_retrans_dt;
|
||||
u_long ts_retrans_xpd;
|
||||
u_long ts_conn_gaveup;
|
||||
|
||||
u_long ts_ER_sent;
|
||||
u_long ts_DT_sent;
|
||||
u_long ts_XPD_sent;
|
||||
u_long ts_AK_sent;
|
||||
u_long ts_XAK_sent;
|
||||
u_long ts_DR_sent;
|
||||
u_long ts_DC_sent;
|
||||
u_long ts_CR_sent;
|
||||
u_long ts_CC_sent;
|
||||
|
||||
u_long ts_ER_rcvd;
|
||||
u_long ts_DT_rcvd;
|
||||
u_long ts_XPD_rcvd;
|
||||
u_long ts_AK_rcvd;
|
||||
u_long ts_XAK_rcvd;
|
||||
u_long ts_DR_rcvd;
|
||||
u_long ts_DC_rcvd;
|
||||
u_long ts_CR_rcvd;
|
||||
u_long ts_CC_rcvd;
|
||||
|
||||
u_long ts_Eticks;
|
||||
u_long ts_Eexpired;
|
||||
u_long ts_Eset;
|
||||
u_long ts_Ecan_act;
|
||||
u_long ts_Cticks;
|
||||
u_long ts_Cexpired;
|
||||
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;
|
||||
|
||||
u_long ts_zdebug; /* zero dref to test timeout on conn estab tp_input.c */
|
||||
u_long ts_ydebug; /* throw away pseudo-random pkts tp_input.c */
|
||||
u_long ts_unused5;
|
||||
u_long ts_unused; /* kludged concat to test separation tp_emit.c */
|
||||
u_long ts_vdebug; /* kludge to test input size checking tp_emit.c */
|
||||
u_long ts_unused4;
|
||||
u_long ts_ldebug; /* faked a renegging of credit */
|
||||
|
||||
u_long ts_mb_small;
|
||||
u_long ts_mb_cluster;
|
||||
u_long ts_mb_len_distr[17];
|
||||
|
||||
u_long ts_eot_input;
|
||||
u_long ts_eot_user;
|
||||
u_long ts_EOT_sent;
|
||||
u_long ts_tp0_conn;
|
||||
u_long ts_tp4_conn;
|
||||
u_long ts_quench;
|
||||
u_long ts_rcvdecbit;
|
||||
|
||||
#define NRTT_CATEGORIES 4
|
||||
/* The 4 categories are:
|
||||
* 0 --> tp_flags: ~TPF_PEER_ON_SAMENET | TPF_NL_PDN
|
||||
* 1 --> tp_flags: ~TPF_PEER_ON_SAMENET | ~TPF_NL_PDN
|
||||
* 2 --> tp_flags: TPF_PEER_ON_SAMENET | ~TPF_NL_PDN
|
||||
* 3 --> tp_flags: TPF_PEER_ON_SAMENET | TPF_NL_PDN
|
||||
*/
|
||||
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
|
||||
* ACK_DUP 0x8 / ACK_EOT 0x10 / ACK_REORDER 0x20
|
||||
* ACK_USRRCV **
|
||||
* ACK_FCC **
|
||||
*/
|
||||
} tp_stat ;
|
||||
#define TP_PM_MAX 0xa /* 10 decimal */
|
||||
|
||||
#define IncStat(x) tp_stat./**/x/**/++
|
||||
|
||||
#ifdef TP_PERF_MEAS
|
||||
|
||||
#define PStat(Tpcb, X) (Tpcb)->tp_p_meas->/**/X/**/
|
||||
#define IncPStat(Tpcb, X) if((Tpcb)->tp_perf_on) (Tpcb)->tp_p_meas->/**/X/**/++
|
||||
|
||||
/* BEWARE OF MACROS like this ^^^ must be sure it's surrounded by {} if
|
||||
* it's used in an if-else statement.
|
||||
*/
|
||||
|
||||
|
||||
/* for perf measurement stuff: maximum window size it can handle */
|
||||
|
||||
struct tp_pmeas {
|
||||
/* the first few are distributions as a fn of window size
|
||||
* only keep enough space for normal format plus 1 slot for
|
||||
* extended format, in case any windows larger than 15 are used
|
||||
*/
|
||||
|
||||
/*
|
||||
* tps_npdusent: for each call to tp_sbsend, we inc the
|
||||
* element representing the number of pdus sent in this call
|
||||
*/
|
||||
int tps_win_lim_by_cdt[TP_PM_MAX+1];
|
||||
int tps_win_lim_by_data[TP_PM_MAX+1];
|
||||
/*
|
||||
* tps_sendtime: Each call to tp_sbsend() is timed. For
|
||||
* Each window size, we keep the running average of the time
|
||||
* taken by tp_sbsend() for each window size.
|
||||
*/
|
||||
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
|
||||
* n_ack_cuz_dup: # times ack sent for receiving a duplicate pkt.
|
||||
* n_ack_cuz_fullwin: # times ack sent for receiving the full window.
|
||||
* n_ack_cuz_doack: # times ack sent for having just reordered data.
|
||||
*/
|
||||
int tps_n_TMsendack;
|
||||
int tps_n_ack_cuz_eot;
|
||||
int tps_n_ack_cuz_fullwin;
|
||||
int tps_n_ack_cuz_reorder;
|
||||
int tps_n_ack_cuz_dup;
|
||||
int tps_n_ack_cuz_strat;
|
||||
/*
|
||||
* when we send an ack: how much less than the "expected" window
|
||||
* did we actually ack. For example: if we last sent a credit
|
||||
* of 10, and we're acking now for whatever reason, and have
|
||||
* only received 6 since our last credit advertisement, we'll
|
||||
* keep the difference, 4, in this variable.
|
||||
*/
|
||||
int tps_ack_early[TP_PM_MAX+1];
|
||||
/*
|
||||
* when we ack, for the # pkts we actually acked w/ this ack,
|
||||
* how much cdt are we advertising?
|
||||
* [ size of window acknowledged ] [ cdt we're giving ]
|
||||
*/
|
||||
int tps_cdt_acked[TP_PM_MAX+1][TP_PM_MAX+1];
|
||||
|
||||
int tps_AK_sent;
|
||||
int tps_XAK_sent;
|
||||
int tps_DT_sent;
|
||||
int tps_XPD_sent;
|
||||
int tps_AK_rcvd;
|
||||
int tps_XAK_rcvd;
|
||||
int tps_DT_rcvd;
|
||||
int tps_XPD_rcvd;
|
||||
|
||||
int Nb_from_sess;
|
||||
int Nb_to_sess;
|
||||
int Nb_to_ll;
|
||||
int Nb_from_ll;
|
||||
};
|
||||
|
||||
#define IFPERF(tpcb) if (tpcb->tp_perf_on && tpcb->tp_p_meas) {
|
||||
#define ENDPERF }
|
||||
|
||||
#else
|
||||
|
||||
int PStat_Junk;
|
||||
#define PStat(tpcb, x) PStat_Junk
|
||||
#define IncPStat(tpcb, x) /* no-op */
|
||||
#define tpmeas(a,b,c,d,e,f) 0
|
||||
|
||||
#define IFPERF(x) if (0) {
|
||||
#define ENDPERF }
|
||||
|
||||
#endif /* TP_PERF_MEAS */
|
||||
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* $Id: tp_states.h,v 1.3 1994/08/05 12:33:30 davidg Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_STATES_H_
|
||||
#define _NETISO_TP_STATES_H_
|
||||
|
||||
#define ST_ERROR 0x0
|
||||
#define TP_CLOSED 0x1
|
||||
#define TP_CRSENT 0x2
|
||||
#define TP_AKWAIT 0x3
|
||||
#define TP_OPEN 0x4
|
||||
#define TP_CLOSING 0x5
|
||||
#define TP_REFWAIT 0x6
|
||||
#define TP_LISTENING 0x7
|
||||
#define TP_CONFIRMING 0x8
|
||||
|
||||
#define tp_NSTATES 0x9
|
||||
|
||||
#endif
|
||||
@@ -1,75 +0,0 @@
|
||||
/* $Header$ */
|
||||
/* $Source$ */
|
||||
{0x3,0x0},
|
||||
{0x6,0x1},
|
||||
{0x6,0x2},
|
||||
{0x6,0x0},
|
||||
{0x2,0x3},
|
||||
{0x2,0x0},
|
||||
{0x1,0x0},
|
||||
{0x5,0x0},
|
||||
{0x4,0x0},
|
||||
{0x7,0x0},
|
||||
{0x7,0x0},
|
||||
{0x1,0x4},
|
||||
{0x8,0x5},
|
||||
{0x8,0x6},
|
||||
{0x4,0x7},
|
||||
{0x3,0x8},
|
||||
{0x1,0x9},
|
||||
{0x2,0xa},
|
||||
{0x6,0xb},
|
||||
{0x1,0xc},
|
||||
{0x6,0xd},
|
||||
{0x6,0xe},
|
||||
{0x6,0xf},
|
||||
{0x6,0x10},
|
||||
{0x1,0x11},
|
||||
{0x6,0x12},
|
||||
{0x5,0x13},
|
||||
{0x4,0x14},
|
||||
{0x4,0x15},
|
||||
{0x2,0x16},
|
||||
{0x6,0x17},
|
||||
{0x3,0x18},
|
||||
{0x4,0x19},
|
||||
{0x4,0x1a},
|
||||
{0x4,0x1b},
|
||||
{0x3,0x1c},
|
||||
{0x4,0x1c},
|
||||
{0x4,0x1d},
|
||||
{0x4,0x1e},
|
||||
{0x4,0x1f},
|
||||
{0x4,0x20},
|
||||
{0x3,0x20},
|
||||
{0x6,0x21},
|
||||
{0x5,0x22},
|
||||
{0x6,0x23},
|
||||
{0x5,0x24},
|
||||
{0x3,0x25},
|
||||
{0x5,0x26},
|
||||
{0x5,0x27},
|
||||
{0x4,0x28},
|
||||
{0x4,0x29},
|
||||
{0x5,0x2a},
|
||||
{0x6,0x2b},
|
||||
{0x1,0x2c},
|
||||
{0x4,0x2d},
|
||||
{0x4,0x2e},
|
||||
{0x4,0x2f},
|
||||
{0x4,0x30},
|
||||
{0x4,0x31},
|
||||
{0x4,0x32},
|
||||
{0x4,0x33},
|
||||
{0x4,0x34},
|
||||
{0x4,0x35},
|
||||
{0x4,0x36},
|
||||
{0x6,0x37},
|
||||
{0x6,0x38},
|
||||
{0x7,0x0},
|
||||
{0x5,0x0},
|
||||
{0x3,0x0},
|
||||
{0x2,0x0},
|
||||
{0x4,0x0},
|
||||
{0x6,0x0},
|
||||
{0x1,0x0},
|
||||
@@ -1,949 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_subr.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_subr.c,v 1.3 1995/04/26 21:32:40 pst Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_subr.c,v 1.3 1995/04/26 21:32:40 pst Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_subr.c,v $
|
||||
*
|
||||
* The main work of data transfer is done here.
|
||||
* These routines are called from tp.trans.
|
||||
* They include the routines that check the validity of acks and Xacks,
|
||||
* (tp_goodack() and tp_goodXack() )
|
||||
* take packets from socket buffers and send them (tp_send()),
|
||||
* drop the data from the socket buffers (tp_sbdrop()),
|
||||
* and put incoming packet data into socket buffers (tp_stash()).
|
||||
*/
|
||||
|
||||
#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/time.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <netiso/tp_ip.h>
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_timer.h>
|
||||
#include <netiso/tp_param.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_pcb.h>
|
||||
#include <netiso/tp_tpdu.h>
|
||||
#include <netiso/tp_trace.h>
|
||||
#include <netiso/tp_meas.h>
|
||||
#include <netiso/tp_seq.h>
|
||||
|
||||
int tp_emit(), tp_sbdrop();
|
||||
int tprexmtthresh = 3;
|
||||
extern int ticks;
|
||||
void tp_send();
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp.trans, when an XAK arrives
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Determines if the sequence number (seq) from the XAK
|
||||
* acks anything new. If so, drop the appropriate tpdu
|
||||
* from the XPD send queue.
|
||||
* RETURN VALUE:
|
||||
* Returns 1 if it did this, 0 if the ack caused no action.
|
||||
*/
|
||||
int
|
||||
tp_goodXack(tpcb, seq)
|
||||
struct tp_pcb *tpcb;
|
||||
SeqNum seq;
|
||||
{
|
||||
|
||||
IFTRACE(D_XPD)
|
||||
tptraceTPCB(TPPTgotXack,
|
||||
seq, tpcb->tp_Xuna, tpcb->tp_Xsndnxt, tpcb->tp_sndnew,
|
||||
tpcb->tp_snduna);
|
||||
ENDTRACE
|
||||
|
||||
if ( seq == tpcb->tp_Xuna ) {
|
||||
tpcb->tp_Xuna = tpcb->tp_Xsndnxt;
|
||||
|
||||
/* DROP 1 packet from the Xsnd socket buf - just so happens
|
||||
* that only one packet can be there at any time
|
||||
* so drop the whole thing. If you allow > 1 packet
|
||||
* the socket buffer, then you'll have to keep
|
||||
* track of how many characters went w/ each XPD tpdu, so this
|
||||
* will get messier
|
||||
*/
|
||||
IFDEBUG(D_XPD)
|
||||
dump_mbuf(tpcb->tp_Xsnd.sb_mb,
|
||||
"tp_goodXack Xsnd before sbdrop");
|
||||
ENDDEBUG
|
||||
|
||||
IFTRACE(D_XPD)
|
||||
tptraceTPCB(TPPTmisc,
|
||||
"goodXack: dropping cc ",
|
||||
(int)(tpcb->tp_Xsnd.sb_cc),
|
||||
0,0,0);
|
||||
ENDTRACE
|
||||
sbdroprecord(&tpcb->tp_Xsnd);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_good_ack()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* updates
|
||||
* smoothed average round trip time (*rtt)
|
||||
* roundtrip time variance (*rtv) - actually deviation, not variance
|
||||
* given the new value (diff)
|
||||
* RETURN VALUE:
|
||||
* void
|
||||
*/
|
||||
|
||||
void
|
||||
tp_rtt_rtv(tpcb)
|
||||
register struct tp_pcb *tpcb;
|
||||
{
|
||||
int old = tpcb->tp_rtt;
|
||||
int delta, elapsed = ticks - tpcb->tp_rttemit;
|
||||
|
||||
if (tpcb->tp_rtt != 0) {
|
||||
/*
|
||||
* rtt is the smoothed round trip time in machine clock ticks (hz).
|
||||
* It is stored as a fixed point number, unscaled (unlike the tcp
|
||||
* srtt). The rationale here is that it is only significant to the
|
||||
* nearest unit of slowtimo, which is at least 8 machine clock ticks
|
||||
* so there is no need to scale. The smoothing is done according
|
||||
* to the same formula as TCP (rtt = rtt*7/8 + measured_rtt/8).
|
||||
*/
|
||||
delta = elapsed - tpcb->tp_rtt;
|
||||
if ((tpcb->tp_rtt += (delta >> TP_RTT_ALPHA)) <= 0)
|
||||
tpcb->tp_rtt = 1;
|
||||
/*
|
||||
* rtv is a smoothed accumulated mean difference, unscaled
|
||||
* for reasons expressed above.
|
||||
* It is smoothed with an alpha of .75, and the round trip timer
|
||||
* will be set to rtt + 4*rtv, also as TCP does.
|
||||
*/
|
||||
if (delta < 0)
|
||||
delta = -delta;
|
||||
if ((tpcb->tp_rtv += ((delta - tpcb->tp_rtv) >> TP_RTV_ALPHA)) <= 0)
|
||||
tpcb->tp_rtv = 1;
|
||||
} else {
|
||||
/*
|
||||
* No rtt measurement yet - use the unsmoothed rtt.
|
||||
* Set the variance to half the rtt (so our first
|
||||
* retransmit happens at 3*rtt)
|
||||
*/
|
||||
tpcb->tp_rtt = elapsed;
|
||||
tpcb->tp_rtv = elapsed >> 1;
|
||||
}
|
||||
tpcb->tp_rttemit = 0;
|
||||
tpcb->tp_rxtshift = 0;
|
||||
/*
|
||||
* Quoting TCP: "the retransmit should happen at rtt + 4 * rttvar.
|
||||
* Because of the way we do the smoothing, srtt and rttvar
|
||||
* will each average +1/2 tick of bias. When we compute
|
||||
* the retransmit timer, we want 1/2 tick of rounding and
|
||||
* 1 extra tick because of +-1/2 tick uncertainty in the
|
||||
* firing of the timer. The bias will give us exactly the
|
||||
* 1.5 tick we need. But, because the bias is
|
||||
* statistical, we have to test that we don't drop below
|
||||
* the minimum feasible timer (which is 2 ticks)."
|
||||
*/
|
||||
TP_RANGESET(tpcb->tp_dt_ticks, TP_REXMTVAL(tpcb),
|
||||
tpcb->tp_peer_acktime, 128 /* XXX */);
|
||||
IFDEBUG(D_RTT)
|
||||
printf("%s tpcb 0x%x, elapsed %d, delta %d, rtt %d, rtv %d, old %d\n",
|
||||
"tp_rtt_rtv:",tpcb,elapsed,delta,tpcb->tp_rtt,tpcb->tp_rtv,old);
|
||||
ENDDEBUG
|
||||
tpcb->tp_rxtcur = tpcb->tp_dt_ticks;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp.trans when an AK arrives
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Given (cdt), the credit from the AK tpdu, and
|
||||
* (seq), the sequence number from the AK tpdu,
|
||||
* tp_goodack() determines if the AK acknowledges something in the send
|
||||
* window, and if so, drops the appropriate packets from the retransmission
|
||||
* list, computes the round trip time, and updates the retransmission timer
|
||||
* based on the new smoothed round trip time.
|
||||
* RETURN VALUE:
|
||||
* Returns 1 if
|
||||
* EITHER it actually acked something heretofore unacknowledged
|
||||
* OR no news but the credit should be processed.
|
||||
* If something heretofore unacked was acked with this sequence number,
|
||||
* the appropriate tpdus are dropped from the retransmission control list,
|
||||
* by calling tp_sbdrop().
|
||||
* No need to see the tpdu itself.
|
||||
*/
|
||||
int
|
||||
tp_goodack(tpcb, cdt, seq, subseq)
|
||||
register struct tp_pcb *tpcb;
|
||||
u_int cdt;
|
||||
register SeqNum seq;
|
||||
u_int subseq;
|
||||
{
|
||||
int old_fcredit;
|
||||
int bang = 0; /* bang --> ack for something heretofore unacked */
|
||||
u_int bytes_acked;
|
||||
|
||||
IFDEBUG(D_ACKRECV)
|
||||
printf("goodack tpcb 0x%x seq 0x%x cdt %d una 0x%x new 0x%x nxt 0x%x\n",
|
||||
tpcb, seq, cdt, tpcb->tp_snduna, tpcb->tp_sndnew, tpcb->tp_sndnxt);
|
||||
ENDDEBUG
|
||||
IFTRACE(D_ACKRECV)
|
||||
tptraceTPCB(TPPTgotack,
|
||||
seq,cdt, tpcb->tp_snduna,tpcb->tp_sndnew,subseq);
|
||||
ENDTRACE
|
||||
|
||||
IFPERF(tpcb)
|
||||
tpmeas(tpcb->tp_lref, TPtime_ack_rcvd, (struct timeval *)0, seq, 0, 0);
|
||||
ENDPERF
|
||||
|
||||
if (seq == tpcb->tp_snduna) {
|
||||
if (subseq < tpcb->tp_r_subseq ||
|
||||
(subseq == tpcb->tp_r_subseq && cdt <= tpcb->tp_fcredit)) {
|
||||
discard_the_ack:
|
||||
IFDEBUG(D_ACKRECV)
|
||||
printf("goodack discard : tpcb 0x%x subseq %d r_subseq %d\n",
|
||||
tpcb, subseq, tpcb->tp_r_subseq);
|
||||
ENDDEBUG
|
||||
goto done;
|
||||
}
|
||||
if (cdt == tpcb->tp_fcredit /*&& thus subseq > tpcb->tp_r_subseq */) {
|
||||
tpcb->tp_r_subseq = subseq;
|
||||
if (tpcb->tp_timer[TM_data_retrans] == 0)
|
||||
tpcb->tp_dupacks = 0;
|
||||
else if (++tpcb->tp_dupacks == tprexmtthresh) {
|
||||
/* partner went out of his way to signal with different
|
||||
subsequences that he has the same lack of an expected
|
||||
packet. This may be an early indiciation of a loss */
|
||||
|
||||
SeqNum onxt = tpcb->tp_sndnxt;
|
||||
struct mbuf *onxt_m = tpcb->tp_sndnxt_m;
|
||||
u_int win = min(tpcb->tp_fcredit,
|
||||
tpcb->tp_cong_win / tpcb->tp_l_tpdusize) / 2;
|
||||
IFDEBUG(D_ACKRECV)
|
||||
printf("%s tpcb 0x%x seq 0x%x rttseq 0x%x onxt 0x%x\n",
|
||||
"goodack dupacks:", tpcb, seq, tpcb->tp_rttseq, onxt);
|
||||
ENDDEBUG
|
||||
if (win < 2)
|
||||
win = 2;
|
||||
tpcb->tp_ssthresh = win * tpcb->tp_l_tpdusize;
|
||||
tpcb->tp_timer[TM_data_retrans] = 0;
|
||||
tpcb->tp_rttemit = 0;
|
||||
tpcb->tp_sndnxt = tpcb->tp_snduna;
|
||||
tpcb->tp_sndnxt_m = 0;
|
||||
tpcb->tp_cong_win = tpcb->tp_l_tpdusize;
|
||||
tp_send(tpcb);
|
||||
tpcb->tp_cong_win = tpcb->tp_ssthresh +
|
||||
tpcb->tp_dupacks * tpcb->tp_l_tpdusize;
|
||||
if (SEQ_GT(tpcb, onxt, tpcb->tp_sndnxt)) {
|
||||
tpcb->tp_sndnxt = onxt;
|
||||
tpcb->tp_sndnxt_m = onxt_m;
|
||||
}
|
||||
|
||||
} else if (tpcb->tp_dupacks > tprexmtthresh) {
|
||||
tpcb->tp_cong_win += tpcb->tp_l_tpdusize;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
} else if (SEQ_LT(tpcb, seq, tpcb->tp_snduna))
|
||||
goto discard_the_ack;
|
||||
/*
|
||||
* If the congestion window was inflated to account
|
||||
* for the other side's cached packets, retract it.
|
||||
*/
|
||||
if (tpcb->tp_dupacks > tprexmtthresh &&
|
||||
tpcb->tp_cong_win > tpcb->tp_ssthresh)
|
||||
tpcb->tp_cong_win = tpcb->tp_ssthresh;
|
||||
tpcb->tp_r_subseq = subseq;
|
||||
old_fcredit = tpcb->tp_fcredit;
|
||||
tpcb->tp_fcredit = cdt;
|
||||
if (cdt > tpcb->tp_maxfcredit)
|
||||
tpcb->tp_maxfcredit = cdt;
|
||||
tpcb->tp_dupacks = 0;
|
||||
|
||||
if (IN_SWINDOW(tpcb, seq, tpcb->tp_snduna, tpcb->tp_sndnew)) {
|
||||
|
||||
tpsbcheck(tpcb, 0);
|
||||
bytes_acked = tp_sbdrop(tpcb, seq);
|
||||
tpsbcheck(tpcb, 1);
|
||||
/*
|
||||
* If transmit timer is running and timed sequence
|
||||
* number was acked, update smoothed round trip time.
|
||||
* Since we now have an rtt measurement, cancel the
|
||||
* timer backoff (cf., Phil Karn's retransmit alg.).
|
||||
* Recompute the initial retransmit timer.
|
||||
*/
|
||||
if (tpcb->tp_rttemit && SEQ_GT(tpcb, seq, tpcb->tp_rttseq))
|
||||
tp_rtt_rtv(tpcb);
|
||||
/*
|
||||
* If all outstanding data is acked, stop retransmit timer.
|
||||
* If there is more data to be acked, restart retransmit
|
||||
* timer, using current (possibly backed-off) value.
|
||||
* OSI combines the keepalive and persistance functions.
|
||||
* So, there is no persistance timer per se, to restart.
|
||||
*/
|
||||
if (tpcb->tp_class != TP_CLASS_0)
|
||||
tpcb->tp_timer[TM_data_retrans] =
|
||||
(seq == tpcb->tp_sndnew) ? 0 : tpcb->tp_rxtcur;
|
||||
/*
|
||||
* When new data is acked, open the congestion window.
|
||||
* If the window gives us less than ssthresh packets
|
||||
* in flight, open exponentially (maxseg per packet).
|
||||
* Otherwise open linearly: maxseg per window
|
||||
* (maxseg^2 / cwnd per packet), plus a constant
|
||||
* fraction of a packet (maxseg/8) to help larger windows
|
||||
* open quickly enough.
|
||||
*/
|
||||
{
|
||||
u_int cw = tpcb->tp_cong_win, incr = tpcb->tp_l_tpdusize;
|
||||
|
||||
incr = min(incr, bytes_acked);
|
||||
if (cw > tpcb->tp_ssthresh)
|
||||
incr = incr * incr / cw + incr / 8;
|
||||
tpcb->tp_cong_win =
|
||||
min(cw + incr, tpcb->tp_sock->so_snd.sb_hiwat);
|
||||
}
|
||||
tpcb->tp_snduna = seq;
|
||||
if (SEQ_LT(tpcb, tpcb->tp_sndnxt, seq)) {
|
||||
tpcb->tp_sndnxt = seq;
|
||||
tpcb->tp_sndnxt_m = 0;
|
||||
}
|
||||
bang++;
|
||||
}
|
||||
|
||||
if( cdt != 0 && old_fcredit == 0 ) {
|
||||
tpcb->tp_sendfcc = 1;
|
||||
}
|
||||
if (cdt == 0) {
|
||||
if (old_fcredit != 0)
|
||||
IncStat(ts_zfcdt);
|
||||
/* The following might mean that the window shrunk */
|
||||
if (tpcb->tp_timer[TM_data_retrans]) {
|
||||
tpcb->tp_timer[TM_data_retrans] = 0;
|
||||
tpcb->tp_timer[TM_sendack] = tpcb->tp_dt_ticks;
|
||||
if (tpcb->tp_sndnxt != tpcb->tp_snduna) {
|
||||
tpcb->tp_sndnxt = tpcb->tp_snduna;
|
||||
tpcb->tp_sndnxt_m = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
tpcb->tp_fcredit = cdt;
|
||||
bang |= (old_fcredit < cdt);
|
||||
|
||||
done:
|
||||
IFDEBUG(D_ACKRECV)
|
||||
printf("goodack returns 0x%x, cdt 0x%x ocdt 0x%x cwin 0x%x\n",
|
||||
bang, cdt, old_fcredit, tpcb->tp_cong_win);
|
||||
ENDDEBUG
|
||||
/* if (bang) XXXXX Very bad to remove this test, but somethings broken */
|
||||
tp_send(tpcb);
|
||||
return (bang);
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_goodack()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* drops everything up TO but not INCLUDING seq # (seq)
|
||||
* from the retransmission queue.
|
||||
*/
|
||||
tp_sbdrop(tpcb, seq)
|
||||
register struct tp_pcb *tpcb;
|
||||
SeqNum seq;
|
||||
{
|
||||
struct sockbuf *sb = &tpcb->tp_sock->so_snd;
|
||||
register int i = SEQ_SUB(tpcb, seq, tpcb->tp_snduna);
|
||||
int oldcc = sb->sb_cc, oldi = i;
|
||||
|
||||
if (i >= tpcb->tp_seqhalf)
|
||||
printf("tp_spdropping too much -- should panic");
|
||||
while (i-- > 0)
|
||||
sbdroprecord(sb);
|
||||
IFDEBUG(D_ACKRECV)
|
||||
printf("tp_sbdroping %d pkts %d bytes on %x at 0x%x\n",
|
||||
oldi, oldcc - sb->sb_cc, tpcb, seq);
|
||||
ENDDEBUG
|
||||
if (sb->sb_flags & SB_NOTIFY)
|
||||
sowwakeup(tpcb->tp_sock);
|
||||
return (oldcc - sb->sb_cc);
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp.trans on user send request, arrival of AK and arrival of XAK
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Emits tpdus starting at sequence number (tpcb->tp_sndnxt).
|
||||
* Emits until a) runs out of data, or b) runs into an XPD mark, or
|
||||
* c) it hits seq number (highseq) limited by cong or credit.
|
||||
*
|
||||
* If you want XPD to buffer > 1 du per socket buffer, you can
|
||||
* modifiy this to issue XPD tpdus also, but then it'll have
|
||||
* to take some argument(s) to distinguish between the type of DU to
|
||||
* hand tp_emit.
|
||||
*
|
||||
* When something is sent for the first time, its time-of-send
|
||||
* is stashed (in system clock ticks rather than pf_slowtimo ticks).
|
||||
* When the ack arrives, the smoothed round-trip time is figured
|
||||
* using this value.
|
||||
*/
|
||||
void
|
||||
tp_send(tpcb)
|
||||
register struct tp_pcb *tpcb;
|
||||
{
|
||||
register int len;
|
||||
register struct mbuf *m;
|
||||
struct mbuf *mb = 0;
|
||||
struct sockbuf *sb = &tpcb->tp_sock->so_snd;
|
||||
unsigned int eotsdu = 0;
|
||||
SeqNum highseq, checkseq;
|
||||
int idle, idleticks, off, cong_win;
|
||||
#ifdef TP_PERF_MEAS
|
||||
int send_start_time = ticks;
|
||||
SeqNum oldnxt = tpcb->tp_sndnxt;
|
||||
#endif /* TP_PERF_MEAS */
|
||||
|
||||
idle = (tpcb->tp_snduna == tpcb->tp_sndnew);
|
||||
if (idle) {
|
||||
idleticks = tpcb->tp_inact_ticks - tpcb->tp_timer[TM_inact];
|
||||
if (idleticks > tpcb->tp_dt_ticks)
|
||||
/*
|
||||
* We have been idle for "a while" and no acks are
|
||||
* expected to clock out any data we send --
|
||||
* slow start to get ack "clock" running again.
|
||||
*/
|
||||
tpcb->tp_cong_win = tpcb->tp_l_tpdusize;
|
||||
}
|
||||
|
||||
cong_win = tpcb->tp_cong_win;
|
||||
highseq = SEQ(tpcb, tpcb->tp_fcredit + tpcb->tp_snduna);
|
||||
if (tpcb->tp_Xsnd.sb_mb)
|
||||
highseq = SEQ_MIN(tpcb, highseq, tpcb->tp_sndnew);
|
||||
|
||||
IFDEBUG(D_DATA)
|
||||
printf("tp_send enter tpcb 0x%x nxt 0x%x win %d high 0x%x\n",
|
||||
tpcb, tpcb->tp_sndnxt, cong_win, highseq);
|
||||
ENDDEBUG
|
||||
IFTRACE(D_DATA)
|
||||
tptraceTPCB( TPPTmisc, "tp_send sndnew snduna",
|
||||
tpcb->tp_sndnew, tpcb->tp_snduna, 0, 0);
|
||||
tptraceTPCB( TPPTmisc, "tp_send tpcb->tp_sndnxt win fcredit congwin",
|
||||
tpcb->tp_sndnxt, cong_win, tpcb->tp_fcredit, tpcb->tp_cong_win);
|
||||
ENDTRACE
|
||||
IFTRACE(D_DATA)
|
||||
tptraceTPCB( TPPTmisc, "tp_send 2 nxt high fcredit congwin",
|
||||
tpcb->tp_sndnxt, highseq, tpcb->tp_fcredit, cong_win);
|
||||
ENDTRACE
|
||||
|
||||
if (tpcb->tp_sndnxt_m)
|
||||
m = tpcb->tp_sndnxt_m;
|
||||
else {
|
||||
off = SEQ_SUB(tpcb, tpcb->tp_sndnxt, tpcb->tp_snduna);
|
||||
for (m = sb->sb_mb; m && off > 0; m = m->m_next)
|
||||
off--;
|
||||
}
|
||||
send:
|
||||
/*
|
||||
* Avoid silly window syndrome here . . . figure out how!
|
||||
*/
|
||||
checkseq = tpcb->tp_sndnum;
|
||||
if (idle && SEQ_LT(tpcb, tpcb->tp_sndnum, highseq))
|
||||
checkseq = highseq; /* i.e. DON'T retain highest assigned packet */
|
||||
|
||||
while ((SEQ_LT(tpcb, tpcb->tp_sndnxt, highseq)) && m && cong_win > 0) {
|
||||
|
||||
eotsdu = (m->m_flags & M_EOR) != 0;
|
||||
len = m->m_pkthdr.len;
|
||||
if (tpcb->tp_sndnxt == checkseq && eotsdu == 0 &&
|
||||
len < (tpcb->tp_l_tpdusize / 2))
|
||||
break; /* Nagle . . . . . */
|
||||
cong_win -= len;
|
||||
/* make a copy - mb goes into the retransmission list
|
||||
* while m gets emitted. m_copy won't copy a zero-length mbuf.
|
||||
*/
|
||||
mb = m;
|
||||
m = m_copy(mb, 0, M_COPYALL);
|
||||
if (m == MNULL)
|
||||
break;
|
||||
IFTRACE(D_STASH)
|
||||
tptraceTPCB( TPPTmisc,
|
||||
"tp_send mcopy nxt high eotsdu len",
|
||||
tpcb->tp_sndnxt, highseq, eotsdu, len);
|
||||
ENDTRACE
|
||||
|
||||
IFDEBUG(D_DATA)
|
||||
printf("tp_sending tpcb 0x%x nxt 0x%x\n",
|
||||
tpcb, tpcb->tp_sndnxt);
|
||||
ENDDEBUG
|
||||
/* when headers are precomputed, may need to fill
|
||||
in checksum here */
|
||||
if (tpcb->tp_sock->so_error =
|
||||
tp_emit(DT_TPDU_type, tpcb, tpcb->tp_sndnxt, eotsdu, m)) {
|
||||
/* error */
|
||||
break;
|
||||
}
|
||||
m = mb->m_nextpkt;
|
||||
tpcb->tp_sndnxt_m = m;
|
||||
if (tpcb->tp_sndnxt == tpcb->tp_sndnew) {
|
||||
SEQ_INC(tpcb, tpcb->tp_sndnew);
|
||||
/*
|
||||
* Time this transmission if not a retransmission and
|
||||
* not currently timing anything.
|
||||
*/
|
||||
if (tpcb->tp_rttemit == 0) {
|
||||
tpcb->tp_rttemit = ticks;
|
||||
tpcb->tp_rttseq = tpcb->tp_sndnxt;
|
||||
}
|
||||
tpcb->tp_sndnxt = tpcb->tp_sndnew;
|
||||
} else
|
||||
SEQ_INC(tpcb, tpcb->tp_sndnxt);
|
||||
/*
|
||||
* Set retransmit timer if not currently set.
|
||||
* Initial value for retransmit timer is smoothed
|
||||
* round-trip time + 2 * round-trip time variance.
|
||||
* Initialize shift counter which is used for backoff
|
||||
* of retransmit time.
|
||||
*/
|
||||
if (tpcb->tp_timer[TM_data_retrans] == 0 &&
|
||||
tpcb->tp_class != TP_CLASS_0) {
|
||||
tpcb->tp_timer[TM_data_retrans] = tpcb->tp_dt_ticks;
|
||||
tpcb->tp_timer[TM_sendack] = tpcb->tp_keepalive_ticks;
|
||||
tpcb->tp_rxtshift = 0;
|
||||
}
|
||||
}
|
||||
if (SEQ_GT(tpcb, tpcb->tp_sndnew, tpcb->tp_sndnum))
|
||||
tpcb->tp_oktonagle = 0;
|
||||
#ifdef TP_PERF_MEAS
|
||||
IFPERF(tpcb)
|
||||
{
|
||||
register int npkts;
|
||||
int elapsed = ticks - send_start_time, *t;
|
||||
struct timeval now;
|
||||
|
||||
npkts = SEQ_SUB(tpcb, tpcb->tp_sndnxt, oldnxt);
|
||||
|
||||
if (npkts > 0)
|
||||
tpcb->tp_Nwindow++;
|
||||
|
||||
if (npkts > TP_PM_MAX)
|
||||
npkts = TP_PM_MAX;
|
||||
|
||||
t = &(tpcb->tp_p_meas->tps_sendtime[npkts]);
|
||||
*t += (t - elapsed) >> TP_RTT_ALPHA;
|
||||
|
||||
if (mb == 0) {
|
||||
IncPStat(tpcb, tps_win_lim_by_data[npkts] );
|
||||
} else {
|
||||
IncPStat(tpcb, tps_win_lim_by_cdt[npkts] );
|
||||
/* not true with congestion-window being used */
|
||||
}
|
||||
now.tv_sec = elapsed / hz;
|
||||
now.tv_usec = (elapsed - (hz * now.tv_sec)) * 1000000 / hz;
|
||||
tpmeas( tpcb->tp_lref,
|
||||
TPsbsend, &elapsed, newseq, tpcb->tp_Nwindow, npkts);
|
||||
}
|
||||
ENDPERF
|
||||
#endif /* TP_PERF_MEAS */
|
||||
|
||||
|
||||
IFTRACE(D_DATA)
|
||||
tptraceTPCB( TPPTmisc,
|
||||
"tp_send at end: new nxt eotsdu error",
|
||||
tpcb->tp_sndnew, tpcb->tp_sndnxt, eotsdu, tpcb->tp_sock->so_error);
|
||||
|
||||
ENDTRACE
|
||||
}
|
||||
|
||||
int TPNagleok;
|
||||
int TPNagled;
|
||||
|
||||
tp_packetize(tpcb, m, eotsdu)
|
||||
register struct tp_pcb *tpcb;
|
||||
register struct mbuf *m;
|
||||
int eotsdu;
|
||||
{
|
||||
register struct mbuf *n;
|
||||
register struct sockbuf *sb = &tpcb->tp_sock->so_snd;
|
||||
int maxsize = tpcb->tp_l_tpdusize
|
||||
- tp_headersize(DT_TPDU_type, tpcb)
|
||||
- (tpcb->tp_use_checksum?4:0) ;
|
||||
int totlen = m->m_pkthdr.len;
|
||||
struct mbuf *m_split();
|
||||
/*
|
||||
* 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.
|
||||
* TODO: allocate space for header and fill it in (once!).
|
||||
*/
|
||||
IFDEBUG(D_DATA)
|
||||
printf("SEND BF: maxsize %d totlen %d eotsdu %d sndnum 0x%x\n",
|
||||
maxsize, totlen, eotsdu, tpcb->tp_sndnum);
|
||||
ENDTRACE
|
||||
if (tpcb->tp_oktonagle) {
|
||||
if ((n = sb->sb_mb) == 0)
|
||||
panic("tp_packetize");
|
||||
while (n->m_act)
|
||||
n = n->m_act;
|
||||
if (n->m_flags & M_EOR)
|
||||
panic("tp_packetize 2");
|
||||
SEQ_INC(tpcb, tpcb->tp_sndnum);
|
||||
if (totlen + n->m_pkthdr.len < maxsize) {
|
||||
/* There is an unsent packet with space, combine data */
|
||||
struct mbuf *old_n = n;
|
||||
tpsbcheck(tpcb,3);
|
||||
n->m_pkthdr.len += totlen;
|
||||
while (n->m_next)
|
||||
n = n->m_next;
|
||||
sbcompress(sb, m, n);
|
||||
tpsbcheck(tpcb,4);
|
||||
n = old_n;
|
||||
TPNagled++;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
while (m) {
|
||||
n = m;
|
||||
if (totlen > maxsize) {
|
||||
if ((m = m_split(n, maxsize, M_WAIT)) == 0)
|
||||
panic("tp_packetize");
|
||||
} else
|
||||
m = 0;
|
||||
totlen -= maxsize;
|
||||
tpsbcheck(tpcb, 5);
|
||||
sbappendrecord(sb, n);
|
||||
tpsbcheck(tpcb, 6);
|
||||
SEQ_INC(tpcb, tpcb->tp_sndnum);
|
||||
}
|
||||
out:
|
||||
if (eotsdu) {
|
||||
n->m_flags |= M_EOR; /* XXX belongs at end */
|
||||
tpcb->tp_oktonagle = 0;
|
||||
} else {
|
||||
SEQ_DEC(tpcb, tpcb->tp_sndnum);
|
||||
tpcb->tp_oktonagle = 1;
|
||||
TPNagleok++;
|
||||
}
|
||||
IFDEBUG(D_DATA)
|
||||
printf("SEND out: oktonagle %d sndnum 0x%x\n",
|
||||
tpcb->tp_oktonagle, tpcb->tp_sndnum);
|
||||
ENDTRACE
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NAME: tp_stash()
|
||||
* CALLED FROM:
|
||||
* tp.trans on arrival of a DT tpdu
|
||||
* FUNCTION, ARGUMENTS, and RETURN VALUE:
|
||||
* Returns 1 if
|
||||
* a) something new arrived and it's got eotsdu_reached bit on,
|
||||
* b) this arrival was caused other out-of-sequence things to be
|
||||
* accepted, or
|
||||
* c) this arrival is the highest seq # for which we last gave credit
|
||||
* (sender just sent a whole window)
|
||||
* In other words, returns 1 if tp should send an ack immediately, 0 if
|
||||
* the ack can wait a while.
|
||||
*
|
||||
* Note: this implementation no longer renegs on credit, (except
|
||||
* when debugging option D_RENEG is on, for the purpose of testing
|
||||
* ack subsequencing), so we don't need to check for incoming tpdus
|
||||
* being in a reneged portion of the window.
|
||||
*/
|
||||
|
||||
tp_stash(tpcb, e)
|
||||
register struct tp_pcb *tpcb;
|
||||
register struct tp_event *e;
|
||||
{
|
||||
register int ack_reason= tpcb->tp_ack_strat & ACK_STRAT_EACH;
|
||||
/* 0--> delay acks until full window */
|
||||
/* 1--> ack each tpdu */
|
||||
#ifndef lint
|
||||
#define E e->ATTR(DT_TPDU)
|
||||
#else /* lint */
|
||||
#define E e->ev_union.EV_DT_TPDU
|
||||
#endif /* lint */
|
||||
|
||||
if ( E.e_eot ) {
|
||||
register struct mbuf *n = E.e_data;
|
||||
n->m_flags |= M_EOR;
|
||||
n->m_act = 0;
|
||||
}
|
||||
IFDEBUG(D_STASH)
|
||||
dump_mbuf(tpcb->tp_sock->so_rcv.sb_mb,
|
||||
"stash: so_rcv before appending");
|
||||
dump_mbuf(E.e_data,
|
||||
"stash: e_data before appending");
|
||||
ENDDEBUG
|
||||
|
||||
IFPERF(tpcb)
|
||||
PStat(tpcb, Nb_from_ll) += E.e_datalen;
|
||||
tpmeas(tpcb->tp_lref, TPtime_from_ll, &e->e_time,
|
||||
E.e_seq, (u_int)PStat(tpcb, Nb_from_ll), (u_int)E.e_datalen);
|
||||
ENDPERF
|
||||
|
||||
if (E.e_seq == tpcb->tp_rcvnxt) {
|
||||
|
||||
IFDEBUG(D_STASH)
|
||||
printf("stash EQ: seq 0x%x datalen 0x%x eot 0x%x\n",
|
||||
E.e_seq, E.e_datalen, E.e_eot);
|
||||
ENDDEBUG
|
||||
|
||||
IFTRACE(D_STASH)
|
||||
tptraceTPCB(TPPTmisc, "stash EQ: seq len eot",
|
||||
E.e_seq, E.e_datalen, E.e_eot, 0);
|
||||
ENDTRACE
|
||||
|
||||
SET_DELACK(tpcb);
|
||||
|
||||
sbappend(&tpcb->tp_sock->so_rcv, E.e_data);
|
||||
|
||||
SEQ_INC( tpcb, tpcb->tp_rcvnxt );
|
||||
/*
|
||||
* move chains from the reassembly queue to the socket buffer
|
||||
*/
|
||||
if (tpcb->tp_rsycnt) {
|
||||
register struct mbuf **mp;
|
||||
struct mbuf **mplim;
|
||||
|
||||
mp = tpcb->tp_rsyq + (tpcb->tp_rcvnxt % tpcb->tp_maxlcredit);
|
||||
mplim = tpcb->tp_rsyq + tpcb->tp_maxlcredit;
|
||||
|
||||
while (tpcb->tp_rsycnt && *mp) {
|
||||
sbappend(&tpcb->tp_sock->so_rcv, *mp);
|
||||
tpcb->tp_rsycnt--;
|
||||
*mp = 0;
|
||||
SEQ_INC(tpcb, tpcb->tp_rcvnxt);
|
||||
ack_reason |= ACK_REORDER;
|
||||
if (++mp == mplim)
|
||||
mp = tpcb->tp_rsyq;
|
||||
}
|
||||
}
|
||||
IFDEBUG(D_STASH)
|
||||
dump_mbuf(tpcb->tp_sock->so_rcv.sb_mb,
|
||||
"stash: so_rcv after appending");
|
||||
ENDDEBUG
|
||||
|
||||
} else {
|
||||
register struct mbuf **mp;
|
||||
SeqNum uwe;
|
||||
|
||||
IFTRACE(D_STASH)
|
||||
tptraceTPCB(TPPTmisc, "stash Reseq: seq rcvnxt lcdt",
|
||||
E.e_seq, tpcb->tp_rcvnxt, tpcb->tp_lcredit, 0);
|
||||
ENDTRACE
|
||||
|
||||
if (tpcb->tp_rsyq == 0)
|
||||
tp_rsyset(tpcb);
|
||||
uwe = SEQ(tpcb, tpcb->tp_rcvnxt + tpcb->tp_maxlcredit);
|
||||
if (tpcb->tp_rsyq == 0 ||
|
||||
!IN_RWINDOW(tpcb, E.e_seq, tpcb->tp_rcvnxt, uwe)) {
|
||||
ack_reason = ACK_DONT;
|
||||
m_freem(E.e_data);
|
||||
} else if (*(mp = tpcb->tp_rsyq + (E.e_seq % tpcb->tp_maxlcredit))) {
|
||||
IFDEBUG(D_STASH)
|
||||
printf("tp_stash - drop & ack\n");
|
||||
ENDDEBUG
|
||||
|
||||
/* retransmission - drop it and force an ack */
|
||||
IncStat(ts_dt_dup);
|
||||
IFPERF(tpcb)
|
||||
IncPStat(tpcb, tps_n_ack_cuz_dup);
|
||||
ENDPERF
|
||||
|
||||
m_freem(E.e_data);
|
||||
ack_reason |= ACK_DUP;
|
||||
} else {
|
||||
*mp = E.e_data;
|
||||
tpcb->tp_rsycnt++;
|
||||
ack_reason = ACK_DONT;
|
||||
}
|
||||
}
|
||||
/* there were some comments of historical interest here. */
|
||||
{
|
||||
LOCAL_CREDIT(tpcb);
|
||||
|
||||
if ( E.e_seq == tpcb->tp_sent_uwe )
|
||||
ack_reason |= ACK_STRAT_FULLWIN;
|
||||
|
||||
IFTRACE(D_STASH)
|
||||
tptraceTPCB(TPPTmisc,
|
||||
"end of stash, eot, ack_reason, sent_uwe ",
|
||||
E.e_eot, ack_reason, tpcb->tp_sent_uwe, 0);
|
||||
ENDTRACE
|
||||
|
||||
if ( ack_reason == ACK_DONT ) {
|
||||
IncStat( ts_ackreason[ACK_DONT] );
|
||||
return 0;
|
||||
} else {
|
||||
IFPERF(tpcb)
|
||||
if(ack_reason & ACK_STRAT_EACH) {
|
||||
IncPStat(tpcb, tps_n_ack_cuz_strat);
|
||||
} else if(ack_reason & ACK_STRAT_FULLWIN) {
|
||||
IncPStat(tpcb, tps_n_ack_cuz_fullwin);
|
||||
} else if(ack_reason & ACK_REORDER) {
|
||||
IncPStat(tpcb, tps_n_ack_cuz_reorder);
|
||||
}
|
||||
tpmeas(tpcb->tp_lref, TPtime_ack_sent, 0,
|
||||
SEQ_ADD(tpcb, E.e_seq, 1), 0, 0);
|
||||
ENDPERF
|
||||
{
|
||||
register int i;
|
||||
|
||||
/* keep track of all reasons that apply */
|
||||
for( i=1; i<_ACK_NUM_REASONS_ ;i++) {
|
||||
if( ack_reason & (1<<i) )
|
||||
IncStat( ts_ackreason[i] );
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* tp_rsyflush - drop all the packets on the reassembly queue.
|
||||
* Do this when closing the socket, or when somebody has changed
|
||||
* the space avaible in the receive socket (XXX).
|
||||
*/
|
||||
tp_rsyflush(tpcb)
|
||||
register struct tp_pcb *tpcb;
|
||||
{
|
||||
register struct mbuf *m, **mp;
|
||||
if (tpcb->tp_rsycnt) {
|
||||
for (mp == tpcb->tp_rsyq + tpcb->tp_maxlcredit;
|
||||
--mp >= tpcb->tp_rsyq; )
|
||||
if (*mp) {
|
||||
tpcb->tp_rsycnt--;
|
||||
m_freem(*mp);
|
||||
}
|
||||
if (tpcb->tp_rsycnt) {
|
||||
printf("tp_rsyflush %x\n", tpcb);
|
||||
tpcb->tp_rsycnt = 0;
|
||||
}
|
||||
}
|
||||
free((caddr_t)tpcb->tp_rsyq, M_PCB);
|
||||
tpcb->tp_rsyq = 0;
|
||||
}
|
||||
|
||||
tp_rsyset(tpcb)
|
||||
register struct tp_pcb *tpcb;
|
||||
{
|
||||
register struct socket *so = tpcb->tp_sock;
|
||||
int maxcredit = tpcb->tp_xtd_format ? 0xffff : 0xf;
|
||||
int old_credit = tpcb->tp_maxlcredit;
|
||||
caddr_t rsyq;
|
||||
|
||||
tpcb->tp_maxlcredit = maxcredit = min(maxcredit,
|
||||
(so->so_rcv.sb_hiwat + tpcb->tp_l_tpdusize)/ tpcb->tp_l_tpdusize);
|
||||
|
||||
if (old_credit == tpcb->tp_maxlcredit && tpcb->tp_rsyq != 0)
|
||||
return;
|
||||
maxcredit *= sizeof(struct mbuf *);
|
||||
if (tpcb->tp_rsyq)
|
||||
tp_rsyflush(tpcb);
|
||||
if (rsyq = (caddr_t)malloc(maxcredit, M_PCB, M_NOWAIT))
|
||||
bzero(rsyq, maxcredit);
|
||||
tpcb->tp_rsyq = (struct mbuf **)rsyq;
|
||||
}
|
||||
|
||||
tpsbcheck(tpcb, i)
|
||||
struct tp_pcb *tpcb;
|
||||
{
|
||||
register struct mbuf *n, *m;
|
||||
register int len = 0, mbcnt = 0, pktlen;
|
||||
struct sockbuf *sb = &tpcb->tp_sock->so_snd;
|
||||
|
||||
for (n = sb->sb_mb; n; n = n->m_nextpkt) {
|
||||
if ((n->m_flags & M_PKTHDR) == 0)
|
||||
panic("tpsbcheck nohdr");
|
||||
pktlen = len + n->m_pkthdr.len;
|
||||
for (m = n; m; m = m->m_next) {
|
||||
len += m->m_len;
|
||||
mbcnt += MSIZE;
|
||||
if (m->m_flags & M_EXT)
|
||||
mbcnt += m->m_ext.ext_size;
|
||||
}
|
||||
if (len != pktlen) {
|
||||
printf("test %d; len %d != pktlen %d on mbuf 0x%x\n",
|
||||
i, len, pktlen, n);
|
||||
panic("tpsbcheck short");
|
||||
}
|
||||
}
|
||||
if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) {
|
||||
printf("test %d: cc %d != %d || mbcnt %d != %d\n", i, len, sb->sb_cc,
|
||||
mbcnt, sb->sb_mbcnt);
|
||||
panic("tpsbcheck");
|
||||
}
|
||||
}
|
||||
@@ -1,882 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_subr2.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_subr2.c,v 1.3 1995/04/26 21:32:41 pst Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_subr2.c,v 1.3 1995/04/26 21:32:41 pst Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_subr2.c,v $
|
||||
*
|
||||
* 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.
|
||||
* tp_indicate: gives indications(signals) to the user process
|
||||
* tp_getoptions: initializes variables that are affected by the options
|
||||
* chosen.
|
||||
*/
|
||||
|
||||
/* this def'n is to cause the expansion of this macro in the
|
||||
* routine tp_local_credit :
|
||||
*/
|
||||
#define LOCAL_CREDIT_EXPAND
|
||||
|
||||
#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>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#undef MNULL
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_param.h>
|
||||
#include <netiso/tp_ip.h>
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_errno.h>
|
||||
#include <netiso/iso_pcb.h>
|
||||
#include <netiso/tp_timer.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_tpdu.h>
|
||||
#include <netiso/tp_pcb.h>
|
||||
#include <netiso/tp_seq.h>
|
||||
#include <netiso/tp_trace.h>
|
||||
#include <netiso/tp_user.h>
|
||||
#include <netiso/cons.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#ifdef TRUE
|
||||
#undef FALSE
|
||||
#undef TRUE
|
||||
#endif
|
||||
#include <netccitt/x25.h>
|
||||
#include <netccitt/pk.h>
|
||||
#include <netccitt/pk_var.h>
|
||||
|
||||
void tp_rsyset();
|
||||
|
||||
/*
|
||||
* NAME: tp_local_credit()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* tp_emit(), tp_usrreq()
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Computes the local credit and stashes it in tpcb->tp_lcredit.
|
||||
* It's a macro in the production system rather than a procdure.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
* This doesn't actually get called in a production system -
|
||||
* the macro gets expanded instead in place of calls to this proc.
|
||||
* But for debugging, we call this and that allows us to add
|
||||
* debugging messages easily here.
|
||||
*/
|
||||
void
|
||||
tp_local_credit(tpcb)
|
||||
struct tp_pcb *tpcb;
|
||||
{
|
||||
LOCAL_CREDIT(tpcb);
|
||||
IFDEBUG(D_CREDIT)
|
||||
printf("ref 0x%x lcdt 0x%x l_tpdusize 0x%x decbit 0x%x\n",
|
||||
tpcb->tp_lref,
|
||||
tpcb->tp_lcredit,
|
||||
tpcb->tp_l_tpdusize,
|
||||
tpcb->tp_decbit,
|
||||
tpcb->tp_cong_win
|
||||
);
|
||||
ENDDEBUG
|
||||
IFTRACE(D_CREDIT)
|
||||
tptraceTPCB(TPPTmisc,
|
||||
"lcdt tpdusz \n",
|
||||
tpcb->tp_lcredit, tpcb->tp_l_tpdusize, 0, 0);
|
||||
ENDTRACE
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: tp_protocol_error()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* tp_driver(), when it doesn't know what to do with
|
||||
* a combo of event, state, predicate
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* print error mesg
|
||||
*
|
||||
* RETURN VALUE:
|
||||
* EIO - always
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
int
|
||||
tp_protocol_error(e,tpcb)
|
||||
struct tp_event *e;
|
||||
struct tp_pcb *tpcb;
|
||||
{
|
||||
printf("TP PROTOCOL ERROR! tpcb 0x%x event 0x%x, state 0x%x\n",
|
||||
tpcb, e->ev_number, tpcb->tp_state);
|
||||
IFTRACE(D_DRIVER)
|
||||
tptraceTPCB(TPPTmisc, "PROTOCOL ERROR tpcb event state",
|
||||
tpcb, e->ev_number, tpcb->tp_state, 0 );
|
||||
ENDTRACE
|
||||
return EIO; /* for lack of anything better */
|
||||
}
|
||||
|
||||
|
||||
/* Not used at the moment */
|
||||
ProtoHook
|
||||
tp_drain()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NAME: tp_indicate()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* tp.trans when XPD arrive, when a connection is being disconnected by
|
||||
* the arrival of a DR or ER, and when a connection times out.
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* (ind) is the type of indication : T_DISCONNECT, T_XPD
|
||||
* (error) is an E* value that will be put in the socket structure
|
||||
* to be passed along to the user later.
|
||||
* Gives a SIGURG to the user process or group indicated by the socket
|
||||
* attached to the tpcb.
|
||||
*
|
||||
* RETURNS: Rien
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
void
|
||||
tp_indicate(ind, tpcb, error)
|
||||
int ind;
|
||||
u_short error;
|
||||
register struct tp_pcb *tpcb;
|
||||
{
|
||||
register struct socket *so = tpcb->tp_sock;
|
||||
IFTRACE(D_INDICATION)
|
||||
tptraceTPCB(TPPTindicate, ind, *(u_short *)(tpcb->tp_lsuffix),
|
||||
*(u_short *)(tpcb->tp_fsuffix), error,so->so_pgid);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_INDICATION)
|
||||
char *ls, *fs;
|
||||
ls = tpcb->tp_lsuffix,
|
||||
fs = tpcb->tp_fsuffix,
|
||||
|
||||
printf(
|
||||
"indicate 0x%x lsuf 0x%02x%02x fsuf 0x%02x%02x err 0x%x noind 0x%x ref 0x%x\n",
|
||||
ind,
|
||||
*ls, *(ls+1), *fs, *(fs+1),
|
||||
error, /*so->so_pgrp,*/
|
||||
tpcb->tp_no_disc_indications,
|
||||
tpcb->tp_lref);
|
||||
ENDDEBUG
|
||||
|
||||
if (ind == ER_TPDU) {
|
||||
register struct mbuf *m;
|
||||
struct tp_disc_reason x;
|
||||
|
||||
if ((so->so_state & SS_CANTRCVMORE) == 0 &&
|
||||
(m = m_get(M_DONTWAIT, MT_OOBDATA)) != 0) {
|
||||
|
||||
x.dr_hdr.cmsg_len = m->m_len = sizeof(x);
|
||||
x.dr_hdr.cmsg_level = SOL_TRANSPORT;
|
||||
x.dr_hdr.cmsg_type= TPOPT_DISC_REASON;
|
||||
x.dr_reason = error;
|
||||
*mtod(m, struct tp_disc_reason *) = x;
|
||||
sbappendrecord(&tpcb->tp_Xrcv, m);
|
||||
error = 0;
|
||||
} else
|
||||
error = ECONNRESET;
|
||||
}
|
||||
so->so_error = error;
|
||||
|
||||
if (ind == T_DISCONNECT) {
|
||||
if (error == 0)
|
||||
so->so_error = ENOTCONN;
|
||||
if ( tpcb->tp_no_disc_indications )
|
||||
return;
|
||||
}
|
||||
IFTRACE(D_INDICATION)
|
||||
tptraceTPCB(TPPTmisc, "doing sohasoutofband(so)", so,0,0,0);
|
||||
ENDTRACE
|
||||
sohasoutofband(so);
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME : tp_getoptions()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* tp.trans whenever we go into OPEN state
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* sets the proper flags and values in the tpcb, to control
|
||||
* the appropriate actions for the given class, options,
|
||||
* sequence space, etc, etc.
|
||||
*
|
||||
* RETURNS: Nada
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
void
|
||||
tp_getoptions(tpcb)
|
||||
struct tp_pcb *tpcb;
|
||||
{
|
||||
tpcb->tp_seqmask =
|
||||
tpcb->tp_xtd_format ? TP_XTD_FMT_MASK : TP_NML_FMT_MASK ;
|
||||
tpcb->tp_seqbit =
|
||||
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));
|
||||
tp_rsyset(tpcb);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: tp_recycle_tsuffix()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* Called when a ref is frozen.
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* allows the suffix to be reused.
|
||||
*
|
||||
* RETURNS: zilch
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
void
|
||||
tp_recycle_tsuffix(tpcb)
|
||||
struct tp_pcb *tpcb;
|
||||
{
|
||||
bzero((caddr_t)tpcb->tp_lsuffix, sizeof( tpcb->tp_lsuffix));
|
||||
bzero((caddr_t)tpcb->tp_fsuffix, sizeof( tpcb->tp_fsuffix));
|
||||
tpcb->tp_fsuffixlen = tpcb->tp_lsuffixlen = 0;
|
||||
|
||||
(tpcb->tp_nlproto->nlp_recycle_suffix)(tpcb->tp_npcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME: tp_quench()
|
||||
*
|
||||
* CALLED FROM:
|
||||
* tp{af}_quench() when ICMP source quench or similar thing arrives.
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Drop the congestion window back to 1.
|
||||
* Congestion window scheme:
|
||||
* Initial value is 1. ("slow start" as Nagle, et. al. call it)
|
||||
* For each good ack that arrives, the congestion window is increased
|
||||
* by 1 (up to max size of logical infinity, which is to say,
|
||||
* it doesn't wrap around).
|
||||
* Source quench causes it to drop back to 1.
|
||||
* tp_send() uses the smaller of (regular window, congestion window).
|
||||
* One retransmission strategy option is to have any retransmission
|
||||
* cause reset the congestion window back to 1.
|
||||
*
|
||||
* (cmd) is either PRC_QUENCH: source quench, or
|
||||
* PRC_QUENCH2: dest. quench (dec bit)
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
void
|
||||
tp_quench( tpcb, cmd )
|
||||
struct tp_pcb *tpcb;
|
||||
int cmd;
|
||||
{
|
||||
IFDEBUG(D_QUENCH)
|
||||
printf("tp_quench tpcb 0x%x ref 0x%x sufx 0x%x\n",
|
||||
tpcb, tpcb->tp_lref, *(u_short *)(tpcb->tp_lsuffix));
|
||||
printf("cong_win 0x%x decbit 0x%x \n",
|
||||
tpcb->tp_cong_win, tpcb->tp_decbit);
|
||||
ENDDEBUG
|
||||
switch(cmd) {
|
||||
case PRC_QUENCH:
|
||||
tpcb->tp_cong_win = tpcb->tp_l_tpdusize;
|
||||
IncStat(ts_quench);
|
||||
break;
|
||||
case PRC_QUENCH2:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NAME: tp_netcmd()
|
||||
*
|
||||
* CALLED FROM:
|
||||
*
|
||||
* FUNCTION and ARGUMENTS:
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
*
|
||||
* NOTES:
|
||||
*/
|
||||
tp_netcmd( tpcb, cmd )
|
||||
struct tp_pcb *tpcb;
|
||||
int cmd;
|
||||
{
|
||||
#ifdef TPCONS
|
||||
struct isopcb *isop;
|
||||
struct pklcd *lcp;
|
||||
|
||||
if (tpcb->tp_netservice != ISO_CONS)
|
||||
return;
|
||||
isop = (struct isopcb *)tpcb->tp_npcb;
|
||||
lcp = (struct pklcd *)isop->isop_chan;
|
||||
switch (cmd) {
|
||||
|
||||
case CONN_CLOSE:
|
||||
case CONN_REFUSE:
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("tp_netcmd(0x%x, 0x%x) NOT IMPLEMENTED\n", tpcb, cmd);
|
||||
break;
|
||||
}
|
||||
#else /* TPCONS */
|
||||
printf("tp_netcmd(): X25 NOT CONFIGURED!!\n");
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_ctloutput() and tp_emit()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Convert a class mask to the highest numeric value it represents.
|
||||
*/
|
||||
|
||||
int
|
||||
tp_mask_to_num(x)
|
||||
u_char x;
|
||||
{
|
||||
register int j;
|
||||
|
||||
for(j = 4; j>=0 ;j--) {
|
||||
if(x & (1<<j))
|
||||
break;
|
||||
}
|
||||
ASSERT( (j == 4) || (j == 0) ); /* for now */
|
||||
if( (j != 4) && (j != 0) ) {
|
||||
printf("ASSERTION ERROR: tp_mask_to_num: x 0x%x j %d\n",
|
||||
x, j);
|
||||
}
|
||||
IFTRACE(D_TPINPUT)
|
||||
tptrace(TPPTmisc, "tp_mask_to_num(x) returns j", x, j, 0, 0);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_TPINPUT)
|
||||
printf("tp_mask_to_num(0x%x) returns 0x%x\n", x, j);
|
||||
ENDDEBUG
|
||||
return j;
|
||||
}
|
||||
|
||||
static
|
||||
copyQOSparms(src, dst)
|
||||
struct tp_conn_param *src, *dst;
|
||||
{
|
||||
/* copy all but the bits stuff at the end */
|
||||
#define COPYSIZE (12 * sizeof(short))
|
||||
|
||||
bcopy((caddr_t)src, (caddr_t)dst, COPYSIZE);
|
||||
dst->p_tpdusize = src->p_tpdusize;
|
||||
dst->p_ack_strat = src->p_ack_strat;
|
||||
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:
|
||||
* -- 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.
|
||||
*
|
||||
*
|
||||
* 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()
|
||||
*
|
||||
* SIDE EFFECTS:
|
||||
* Determines recommended tpdusize, buffering and intial delays
|
||||
* based on information cached on the route.
|
||||
*/
|
||||
int
|
||||
tp_route_to( m, tpcb, channel)
|
||||
struct mbuf *m;
|
||||
register struct tp_pcb *tpcb;
|
||||
caddr_t channel;
|
||||
{
|
||||
register struct sockaddr_iso *siso; /* NOTE: this may be a sockaddr_in */
|
||||
extern struct tp_conn_param tp_conn_param[];
|
||||
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)
|
||||
tptraceTPCB(TPPTmisc,
|
||||
"route_to: so afi netservice class",
|
||||
tpcb->tp_sock, siso->siso_addr.isoa_genaddr[0], tpcb->tp_netservice,
|
||||
tpcb->tp_class);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_CONN)
|
||||
printf("tp_route_to( m x%x, channel 0x%x, tpcb 0x%x netserv 0x%x)\n",
|
||||
m, channel, tpcb, tpcb->tp_netservice);
|
||||
printf("m->mlen x%x, m->m_data:\n", m->m_len);
|
||||
dump_buf(mtod(m, caddr_t), m->m_len);
|
||||
ENDDEBUG
|
||||
if (channel) {
|
||||
#ifdef TPCONS
|
||||
struct pklcd *lcp = (struct pklcd *)channel;
|
||||
struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext,
|
||||
*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_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);
|
||||
isop->isop_socket = tpcb->tp_sock;
|
||||
} else
|
||||
/* there are already connections sharing this */;
|
||||
#endif
|
||||
} else {
|
||||
switch (siso->siso_family) {
|
||||
default:
|
||||
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
|
||||
}
|
||||
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)
|
||||
goto done;
|
||||
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);
|
||||
ENDDEBUG
|
||||
IFTRACE(D_CONN)
|
||||
tptraceTPCB(TPPTmisc, "route_to: returns: error netserv class", error,
|
||||
tpcb->tp_netservice, tpcb->tp_class, 0);
|
||||
ENDTRACE
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* class zero version */
|
||||
void
|
||||
tp0_stash( tpcb, e )
|
||||
register struct tp_pcb *tpcb;
|
||||
register struct tp_event *e;
|
||||
{
|
||||
#ifndef lint
|
||||
#define E e->ATTR(DT_TPDU)
|
||||
#else /* lint */
|
||||
#define E e->ev_union.EV_DT_TPDU
|
||||
#endif /* lint */
|
||||
|
||||
register struct sockbuf *sb = &tpcb->tp_sock->so_rcv;
|
||||
register struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
|
||||
|
||||
IFPERF(tpcb)
|
||||
PStat(tpcb, Nb_from_ll) += E.e_datalen;
|
||||
tpmeas(tpcb->tp_lref, TPtime_from_ll, &e->e_time,
|
||||
E.e_seq, PStat(tpcb, Nb_from_ll), E.e_datalen);
|
||||
ENDPERF
|
||||
|
||||
IFDEBUG(D_STASH)
|
||||
printf("stash EQ: seq 0x%x datalen 0x%x eot 0x%x",
|
||||
E.e_seq, E.e_datalen, E.e_eot);
|
||||
ENDDEBUG
|
||||
|
||||
IFTRACE(D_STASH)
|
||||
tptraceTPCB(TPPTmisc, "stash EQ: seq len eot",
|
||||
E.e_seq, E.e_datalen, E.e_eot, 0);
|
||||
ENDTRACE
|
||||
|
||||
if ( E.e_eot ) {
|
||||
register struct mbuf *n = E.e_data;
|
||||
n->m_flags |= M_EOR;
|
||||
n->m_act = MNULL; /* set on tp_input */
|
||||
}
|
||||
sbappend(sb, E.e_data);
|
||||
IFDEBUG(D_STASH)
|
||||
dump_mbuf(sb->sb_mb, "stash 0: so_rcv after appending");
|
||||
ENDDEBUG
|
||||
if (tpcb->tp_netservice != ISO_CONS)
|
||||
printf("tp0_stash: tp running over something wierd\n");
|
||||
else {
|
||||
register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
|
||||
pk_flowcontrol(lcp, sbspace(sb) <= 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tp0_openflow(tpcb)
|
||||
register struct tp_pcb *tpcb;
|
||||
{
|
||||
register struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
|
||||
if (tpcb->tp_netservice != ISO_CONS)
|
||||
printf("tp0_openflow: tp running over something wierd\n");
|
||||
else {
|
||||
register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
|
||||
if (lcp->lcd_rxrnr_condition)
|
||||
pk_flowcontrol(lcp, 0, 0);
|
||||
}
|
||||
}
|
||||
#ifndef TPCONS
|
||||
static
|
||||
pk_flowcontrol() {}
|
||||
#endif
|
||||
|
||||
#ifdef TP_PERF_MEAS
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_ctloutput() when the user sets TPOPT_PERF_MEAS on
|
||||
* and tp_newsocket() when a new connection is made from
|
||||
* a listening socket with tp_perf_on == true.
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* (tpcb) is the usual; this procedure gets a clear cluster mbuf for
|
||||
* a tp_pmeas structure, and makes tpcb->tp_p_meas point to it.
|
||||
* RETURN VALUE:
|
||||
* ENOBUFS if it cannot get a cluster mbuf.
|
||||
*/
|
||||
|
||||
int
|
||||
tp_setup_perf(tpcb)
|
||||
register struct tp_pcb *tpcb;
|
||||
{
|
||||
register struct mbuf *q;
|
||||
|
||||
if( tpcb->tp_p_meas == 0 ) {
|
||||
MGET(q, M_WAITOK, MT_PCB);
|
||||
if (q == 0)
|
||||
return ENOBUFS;
|
||||
MCLGET(q, M_WAITOK);
|
||||
if ((q->m_flags & M_EXT) == 0) {
|
||||
(void) m_free(q);
|
||||
return ENOBUFS;
|
||||
}
|
||||
q->m_len = sizeof (struct tp_pmeas);
|
||||
tpcb->tp_p_mbuf = q;
|
||||
tpcb->tp_p_meas = mtod(q, struct tp_pmeas *);
|
||||
bzero( (caddr_t)tpcb->tp_p_meas, sizeof (struct tp_pmeas) );
|
||||
IFDEBUG(D_PERF_MEAS)
|
||||
printf(
|
||||
"tpcb 0x%x so 0x%x ref 0x%x tp_p_meas 0x%x tp_perf_on 0x%x\n",
|
||||
tpcb, tpcb->tp_sock, tpcb->tp_lref,
|
||||
tpcb->tp_p_meas, tpcb->tp_perf_on);
|
||||
ENDDEBUG
|
||||
tpcb->tp_perf_on = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* TP_PERF_MEAS */
|
||||
|
||||
#ifdef ARGO_DEBUG
|
||||
dump_addr (addr)
|
||||
register struct sockaddr *addr;
|
||||
{
|
||||
switch( addr->sa_family ) {
|
||||
case AF_INET:
|
||||
dump_inaddr((struct sockaddr_in *)addr);
|
||||
break;
|
||||
#ifdef ISO
|
||||
case AF_ISO:
|
||||
dump_isoaddr((struct sockaddr_iso *)addr);
|
||||
break;
|
||||
#endif /* ISO */
|
||||
default:
|
||||
printf("BAD AF: 0x%x\n", addr->sa_family);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_COLUMNS 8
|
||||
/*
|
||||
* Dump the buffer to the screen in a readable format. Format is:
|
||||
*
|
||||
* hex/dec where hex is the hex format, dec is the decimal format.
|
||||
* columns of hex/dec numbers will be printed, followed by the
|
||||
* character representations (if printable).
|
||||
*/
|
||||
Dump_buf(buf, len)
|
||||
caddr_t buf;
|
||||
int len;
|
||||
{
|
||||
int i,j;
|
||||
#define Buf ((u_char *)buf)
|
||||
printf("Dump buf 0x%x len 0x%x\n", buf, len);
|
||||
for (i = 0; i < len; i += MAX_COLUMNS) {
|
||||
printf("+%d:\t", i);
|
||||
for (j = 0; j < MAX_COLUMNS; j++) {
|
||||
if (i + j < len) {
|
||||
printf("%x/%d\t", Buf[i+j], Buf[i+j]);
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < MAX_COLUMNS; j++) {
|
||||
if (i + j < len) {
|
||||
if (((Buf[i+j]) > 31) && ((Buf[i+j]) < 128))
|
||||
printf("%c", Buf[i+j]);
|
||||
else
|
||||
printf(".");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
#endif /* ARGO_DEBUG */
|
||||
@@ -1,378 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_timer.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_timer.c,v 1.2 1994/08/02 07:51:27 davidg Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_timer.c,v 1.2 1994/08/02 07:51:27 davidg Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_timer.c,v $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/param.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/tp_trace.h>
|
||||
#include <netiso/tp_seq.h>
|
||||
|
||||
struct tp_ref *tp_ref;
|
||||
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:
|
||||
* at autoconfig time from tp_init()
|
||||
* a combo of event, state, predicate
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* initialize data structures for the timers
|
||||
*/
|
||||
void
|
||||
tp_timerinit()
|
||||
{
|
||||
register int s;
|
||||
/*
|
||||
* Initialize storage
|
||||
*/
|
||||
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.trans all over
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Set an E type timer.
|
||||
*/
|
||||
void
|
||||
tp_etimeout(tpcb, fun, ticks)
|
||||
register struct tp_pcb *tpcb;
|
||||
int fun; /* function to be called */
|
||||
int ticks;
|
||||
{
|
||||
|
||||
register u_int *callp;
|
||||
IFDEBUG(D_TIMER)
|
||||
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", tpcb->tp_lref,
|
||||
tpcb->tp_state, ticks, tp_stat.ts_Eticks);
|
||||
ENDTRACE
|
||||
if (tpcb == 0)
|
||||
return;
|
||||
IncStat(ts_Eset);
|
||||
if (ticks == 0)
|
||||
ticks = 1;
|
||||
callp = tpcb->tp_timer + fun;
|
||||
if (*callp == 0 || *callp > ticks)
|
||||
*callp = ticks;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp.trans all over
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Cancel all occurrences of E-timer function (fun) for reference (refp)
|
||||
*/
|
||||
void
|
||||
tp_euntimeout(tpcb, fun)
|
||||
register struct tp_pcb *tpcb;
|
||||
int fun;
|
||||
{
|
||||
IFTRACE(D_TIMER)
|
||||
tptrace(TPPTmisc, "tp_euntimeout ref", tpcb->tp_lref, 0, 0, 0);
|
||||
ENDTRACE
|
||||
|
||||
if (tpcb)
|
||||
tpcb->tp_timer[fun] = 0;
|
||||
}
|
||||
|
||||
/**************** c timers **********************
|
||||
*
|
||||
* These are not chained together; they sit
|
||||
* in the tp_ref structure. they are the kind that
|
||||
* are typically cancelled so it's faster not to
|
||||
* mess with the chains
|
||||
*/
|
||||
#endif
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* the clock, every 500 ms
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Look for open references with active timers.
|
||||
* If they exist, call the appropriate timer routines to update
|
||||
* the timers and possibly generate events.
|
||||
*/
|
||||
ProtoHook
|
||||
tp_slowtimo()
|
||||
{
|
||||
register u_int *cp;
|
||||
register struct tp_ref *rp;
|
||||
struct tp_pcb *tpcb;
|
||||
struct tp_event E;
|
||||
int s = splnet(), t;
|
||||
|
||||
/* check only open reference structures */
|
||||
IncStat(ts_Cticks);
|
||||
/* 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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
int
|
||||
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()
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Set a C type timer of type (which) to go off after (ticks) time.
|
||||
*/
|
||||
void
|
||||
tp_ctimeout(tpcb, which, ticks)
|
||||
register struct tp_pcb *tpcb;
|
||||
int which, ticks;
|
||||
{
|
||||
|
||||
IFTRACE(D_TIMER)
|
||||
tptrace(TPPTmisc, "tp_ctimeout ref which tpcb active",
|
||||
tpcb->tp_lref, which, tpcb, tpcb->tp_timer[which]);
|
||||
ENDTRACE
|
||||
if(tpcb->tp_timer[which])
|
||||
IncStat(ts_Ccan_act);
|
||||
IncStat(ts_Cset);
|
||||
if (ticks <= 0)
|
||||
ticks = 1;
|
||||
tpcb->tp_timer[which] = ticks;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp.trans
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Version of tp_ctimeout that resets the C-type time if the
|
||||
* parameter (ticks) is > the current value of the timer.
|
||||
*/
|
||||
void
|
||||
tp_ctimeout_MIN(tpcb, which, ticks)
|
||||
register struct tp_pcb *tpcb;
|
||||
int which, ticks;
|
||||
{
|
||||
IFTRACE(D_TIMER)
|
||||
tptrace(TPPTmisc, "tp_ctimeout_MIN ref which tpcb active",
|
||||
tpcb->tp_lref, which, tpcb, tpcb->tp_timer[which]);
|
||||
ENDTRACE
|
||||
IncStat(ts_Cset);
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp.trans
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Cancel the (which) timer in the ref structure indicated by (refp).
|
||||
*/
|
||||
void
|
||||
tp_cuntimeout(tpcb, which)
|
||||
register struct tp_pcb *tpcb;
|
||||
int which;
|
||||
{
|
||||
IFDEBUG(D_TIMER)
|
||||
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, tpcb->tp_timer[which], 0);
|
||||
ENDTRACE
|
||||
|
||||
if (tpcb->tp_timer[which])
|
||||
IncStat(ts_Ccan_act);
|
||||
else
|
||||
IncStat(ts_Ccan_inact);
|
||||
tpcb->tp_timer[which] = 0;
|
||||
}
|
||||
#endif
|
||||
@@ -1,94 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_timer.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_timer.h,v 1.3 1994/08/21 06:14:30 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_TIMER_H_
|
||||
#define _NETISO_TP_TIMER_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_timer.h,v 1.3 1994/08/21 06:14:30 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_timer.h,v $
|
||||
*
|
||||
* ARGO TP
|
||||
* The callout structures used by the tp timers.
|
||||
*/
|
||||
|
||||
#define SET_DELACK(t) {\
|
||||
(t)->tp_flags |= TPF_DELACK; \
|
||||
if ((t)->tp_fasttimeo == 0)\
|
||||
{ (t)->tp_fasttimeo = tp_ftimeolist; tp_ftimeolist = (t); } }
|
||||
|
||||
#ifdef ARGO_DEBUG
|
||||
#define TP_DEBUG_TIMERS
|
||||
#endif
|
||||
|
||||
#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
|
||||
@@ -1,297 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_tpdu.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_tpdu.h,v 1.4 1995/05/30 08:11:38 rgrimes Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_TPDU_H_
|
||||
#define _NETISO_TP_TPDU_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_tpdu.h,v 1.4 1995/05/30 08:11:38 rgrimes Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_tpdu.h,v $
|
||||
*
|
||||
* This ghastly set of macros makes it possible to
|
||||
* refer to tpdu structures without going mad.
|
||||
*/
|
||||
|
||||
#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
|
||||
*/
|
||||
struct tpdu_fixed {
|
||||
u_char _tpduf_li:8, /* length indicator */
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
_tpduf_cdt: 4, /* credit */
|
||||
_tpduf_type: 4; /* type of tpdu (DT, CR, etc.) */
|
||||
#endif
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
_tpduf_type: 4, /* type of tpdu (DT, CR, etc.) */
|
||||
_tpduf_cdt: 4; /* credit */
|
||||
#endif
|
||||
u_short _tpduf_dref; /* destination ref; not in DT in class 0 */
|
||||
};
|
||||
|
||||
#define tpdu_li _tpduf._tpduf_li
|
||||
#define tpdu_type _tpduf._tpduf_type
|
||||
#define tpdu_cdt _tpduf._tpduf_cdt
|
||||
#define tpdu_dref _tpduf._tpduf_dref
|
||||
|
||||
struct tp0du {
|
||||
u_char _tp0_li,
|
||||
_tp0_cdt_type, /* same as in tpdu_fixed */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
_tp0_eot: 1, /* eot */
|
||||
_tp0_mbz: 7, /* must be zero */
|
||||
#endif
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
_tp0_mbz: 7, /* must be zero */
|
||||
_tp0_eot: 1, /* eot */
|
||||
#endif
|
||||
_tp0_notused: 8; /* data begins on this octet */
|
||||
};
|
||||
|
||||
#define tp0du_eot _tp0_eot
|
||||
#define tp0du_mbz _tp0_mbz
|
||||
|
||||
/*
|
||||
* This is used when the extended format sequence numbers are
|
||||
* being sent and received.
|
||||
*/
|
||||
/*
|
||||
* the seqeot field is an int that overlays the seq
|
||||
* and eot fields, this allows the htonl operation
|
||||
* to be applied to the entire 32 bit quantity, and
|
||||
* simplifies the structure definitions.
|
||||
*/
|
||||
union seq_type {
|
||||
struct {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
unsigned int st_eot:1, /* end-of-tsdu */
|
||||
st_seq:31; /* 31 bit sequence number */
|
||||
#endif
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
unsigned int st_seq:31, /* 31 bit sequence number */
|
||||
st_eot:1; /* end-of-tsdu */
|
||||
#endif
|
||||
} st;
|
||||
unsigned int s_seqeot;
|
||||
#define s_eot st.st_eot
|
||||
#define s_seq st.st_seq
|
||||
};
|
||||
|
||||
/* Then most tpdu types have a portion that is always present but
|
||||
* differs among the tpdu types :
|
||||
*/
|
||||
union tpdu_fixed_rest {
|
||||
|
||||
struct {
|
||||
u_short _tpdufr_sref, /* source reference */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
_tpdufr_class: 4, /* class [ ISO 8073 13.3.3.e ] */
|
||||
_tpdufr_opt: 4, /* options [ ISO 8073 13.3.3.e ] */
|
||||
#endif
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
_tpdufr_opt: 4, /* options [ ISO 8073 13.3.3.e ] */
|
||||
_tpdufr_class: 4, /* class [ ISO 8073 13.3.3.e ] */
|
||||
#endif
|
||||
_tpdufr_xx: 8; /* unused */
|
||||
} CRCC;
|
||||
|
||||
#define tpdu_CRli _tpduf._tpduf_li
|
||||
#define tpdu_CRtype _tpduf._tpduf_type
|
||||
#define tpdu_CRcdt _tpduf._tpduf_cdt
|
||||
#define tpdu_CRdref_0 _tpduf._tpduf_dref
|
||||
#define tpdu_CRsref _tpdufr.CRCC._tpdufr_sref
|
||||
#define tpdu_sref _tpdufr.CRCC._tpdufr_sref
|
||||
#define tpdu_CRclass _tpdufr.CRCC._tpdufr_class
|
||||
#define tpdu_CRoptions _tpdufr.CRCC._tpdufr_opt
|
||||
|
||||
#define tpdu_CCli _tpduf._tpduf_li
|
||||
#define tpdu_CCtype _tpduf._tpduf_type
|
||||
#define tpdu_CCcdt _tpduf._tpduf_cdt
|
||||
#define tpdu_CCdref _tpduf._tpduf_dref
|
||||
#define tpdu_CCsref _tpdufr.CRCC._tpdufr_sref
|
||||
#define tpdu_CCclass _tpdufr.CRCC._tpdufr_class
|
||||
#define tpdu_CCoptions _tpdufr.CRCC._tpdufr_opt
|
||||
|
||||
/* OPTIONS and ADDL OPTIONS bits */
|
||||
#define TPO_USE_EFC 0x1
|
||||
#define TPO_XTD_FMT 0x2
|
||||
#define TPAO_USE_TXPD 0x1
|
||||
#define TPAO_NO_CSUM 0x2
|
||||
#define TPAO_USE_RCC 0x4
|
||||
#define TPAO_USE_NXPD 0x8
|
||||
|
||||
struct {
|
||||
unsigned short _tpdufr_sref; /* source reference */
|
||||
unsigned char _tpdufr_reason; /* [ ISO 8073 13.5.3.d ] */
|
||||
} DR;
|
||||
#define tpdu_DRli _tpduf._tpduf_li
|
||||
#define tpdu_DRtype _tpduf._tpduf_type
|
||||
#define tpdu_DRdref _tpduf._tpduf_dref
|
||||
#define tpdu_DRsref _tpdufr.DR._tpdufr_sref
|
||||
#define tpdu_DRreason _tpdufr.DR._tpdufr_reason
|
||||
|
||||
unsigned short _tpdufr_sref; /* source reference */
|
||||
|
||||
#define tpdu_DCli _tpduf._tpduf_li
|
||||
#define tpdu_DCtype _tpduf._tpduf_type
|
||||
#define tpdu_DCdref _tpduf._tpduf_dref
|
||||
#define tpdu_DCsref _tpdufr._tpdufr_sref
|
||||
|
||||
struct {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
unsigned char _tpdufr_eot:1, /* end-of-tsdu */
|
||||
_tpdufr_seq:7; /* 7 bit sequence number */
|
||||
#endif
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
unsigned char _tpdufr_seq:7, /* 7 bit sequence number */
|
||||
_tpdufr_eot:1; /* end-of-tsdu */
|
||||
#endif
|
||||
}SEQEOT;
|
||||
struct {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
unsigned int _tpdufr_Xeot:1, /* end-of-tsdu */
|
||||
_tpdufr_Xseq:31; /* 31 bit sequence number */
|
||||
#endif
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
unsigned int _tpdufr_Xseq:31, /* 31 bit sequence number */
|
||||
_tpdufr_Xeot:1; /* end-of-tsdu */
|
||||
#endif
|
||||
}SEQEOT31;
|
||||
unsigned int _tpdufr_Xseqeot;
|
||||
#define tpdu_seqeotX _tpdufr._tpdufr_Xseqeot
|
||||
|
||||
#define tpdu_DTli _tpduf._tpduf_li
|
||||
#define tpdu_DTtype _tpduf._tpduf_type
|
||||
#define tpdu_DTdref _tpduf._tpduf_dref
|
||||
#define tpdu_DTseq _tpdufr.SEQEOT._tpdufr_seq
|
||||
#define tpdu_DTeot _tpdufr.SEQEOT._tpdufr_eot
|
||||
#define tpdu_DTseqX _tpdufr.SEQEOT31._tpdufr_Xseq
|
||||
#define tpdu_DTeotX _tpdufr.SEQEOT31._tpdufr_Xeot
|
||||
|
||||
#define tpdu_XPDli _tpduf._tpduf_li
|
||||
#define tpdu_XPDtype _tpduf._tpduf_type
|
||||
#define tpdu_XPDdref _tpduf._tpduf_dref
|
||||
#define tpdu_XPDseq _tpdufr.SEQEOT._tpdufr_seq
|
||||
#define tpdu_XPDeot _tpdufr.SEQEOT._tpdufr_eot
|
||||
#define tpdu_XPDseqX _tpdufr.SEQEOT31._tpdufr_Xseq
|
||||
#define tpdu_XPDeotX _tpdufr.SEQEOT31._tpdufr_Xeot
|
||||
|
||||
struct {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
unsigned _tpdufr_yrseq0:1, /* always zero */
|
||||
_tpdufr_yrseq:31; /* [ ISO 8073 13.9.3.d ] */
|
||||
#endif
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
unsigned _tpdufr_yrseq:31, /* [ ISO 8073 13.9.3.d ] */
|
||||
_tpdufr_yrseq0:1; /* always zero */
|
||||
#endif
|
||||
unsigned short _tpdufr_cdt; /* [ ISO 8073 13.9.3.b ] */
|
||||
} AK31;
|
||||
|
||||
#define tpdu_AKli _tpduf._tpduf_li
|
||||
#define tpdu_AKtype _tpduf._tpduf_type
|
||||
#define tpdu_AKdref _tpduf._tpduf_dref
|
||||
#define tpdu_AKseq _tpdufr.SEQEOT._tpdufr_seq
|
||||
#define tpdu_AKseqX _tpdufr.AK31._tpdufr_yrseq
|
||||
/* location of cdt depends on size of seq. numbers */
|
||||
#define tpdu_AKcdt _tpduf._tpduf_cdt
|
||||
#define tpdu_AKcdtX _tpdufr.AK31._tpdufr_cdt
|
||||
|
||||
#define tpdu_XAKli _tpduf._tpduf_li
|
||||
#define tpdu_XAKtype _tpduf._tpduf_type
|
||||
#define tpdu_XAKdref _tpduf._tpduf_dref
|
||||
#define tpdu_XAKseq _tpdufr.SEQEOT._tpdufr_seq
|
||||
#define tpdu_XAKseqX _tpdufr.SEQEOT31._tpdufr_Xseq
|
||||
|
||||
unsigned char _tpdu_ERreason; /* [ ISO 8073 13.12.3.c ] */
|
||||
|
||||
#define tpdu_ERli _tpduf._tpduf_li
|
||||
#define tpdu_ERtype _tpduf._tpduf_type
|
||||
#define tpdu_ERdref _tpduf._tpduf_dref
|
||||
#define tpdu_ERreason _tpdufr._tpdu_ERreason
|
||||
|
||||
};
|
||||
|
||||
struct tpdu {
|
||||
struct tpdu_fixed _tpduf;
|
||||
union tpdu_fixed_rest _tpdufr;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,177 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_trace.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_trace.c,v 1.3 1995/04/26 21:32:41 pst Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_trace.c,v 1.3 1995/04/26 21:32:41 pst Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_trace.c,v $
|
||||
*
|
||||
* 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.
|
||||
* Unfortunately this gets too big pretty easily. Pcbs were removed
|
||||
* from the tracing when the kernel got too big to boot.
|
||||
*/
|
||||
|
||||
#define TP_TRACEFILE
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <netiso/tp_param.h>
|
||||
#include <netiso/tp_timer.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_param.h>
|
||||
#include <netiso/tp_ip.h>
|
||||
#include <netiso/tp_pcb.h>
|
||||
#include <netiso/tp_tpdu.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_trace.h>
|
||||
|
||||
#ifdef TPPT
|
||||
static tp_seq = 0;
|
||||
u_char tp_traceflags[128];
|
||||
|
||||
/*
|
||||
* The argument tpcb is the obvious.
|
||||
* event here is just the type of trace event - TPPTmisc, etc.
|
||||
* The rest of the arguments have different uses depending
|
||||
* on the type of trace event.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
/*VARARGS*/
|
||||
|
||||
void
|
||||
tpTrace(tpcb, event, arg, src, len, arg4, arg5)
|
||||
struct tp_pcb *tpcb;
|
||||
u_int event, arg;
|
||||
u_int src;
|
||||
u_int len;
|
||||
u_int arg4;
|
||||
u_int arg5;
|
||||
{
|
||||
register struct tp_Trace *tp;
|
||||
|
||||
tp = &tp_Trace[tp_Tracen++];
|
||||
tp_Tracen %= TPTRACEN;
|
||||
|
||||
tp->tpt_event = event;
|
||||
tp->tpt_tseq = tp_seq++;
|
||||
tp->tpt_arg = arg;
|
||||
if(tpcb)
|
||||
tp->tpt_arg2 = tpcb->tp_lref;
|
||||
bcopy( (caddr_t)&time, (caddr_t)&tp->tpt_time, sizeof(struct timeval) );
|
||||
|
||||
switch(event) {
|
||||
|
||||
case TPPTertpdu:
|
||||
bcopy((caddr_t)src, (caddr_t)&tp->tpt_ertpdu,
|
||||
(unsigned)MIN((int)len, sizeof(struct tp_Trace)));
|
||||
break;
|
||||
|
||||
case TPPTusrreq:
|
||||
case TPPTmisc:
|
||||
|
||||
/* arg is a string */
|
||||
bcopy((caddr_t)arg, (caddr_t)tp->tpt_str,
|
||||
(unsigned)MIN(1+strlen((caddr_t) arg), TPTRACE_STRLEN));
|
||||
tp->tpt_m2 = src;
|
||||
tp->tpt_m3 = len;
|
||||
tp->tpt_m4 = arg4;
|
||||
tp->tpt_m1 = arg5;
|
||||
break;
|
||||
|
||||
case TPPTgotXack:
|
||||
case TPPTXack:
|
||||
case TPPTsendack:
|
||||
case TPPTgotack:
|
||||
case TPPTack:
|
||||
case TPPTindicate:
|
||||
default:
|
||||
case TPPTdriver:
|
||||
tp->tpt_m2 = arg;
|
||||
tp->tpt_m3 = src;
|
||||
tp->tpt_m4 = len;
|
||||
tp->tpt_m5 = arg4;
|
||||
tp->tpt_m1 = arg5;
|
||||
break;
|
||||
case TPPTparam:
|
||||
bcopy((caddr_t)src, (caddr_t)&tp->tpt_param, sizeof(struct tp_param));
|
||||
break;
|
||||
case TPPTref:
|
||||
bcopy((caddr_t)src, (caddr_t)&tp->tpt_ref, sizeof(struct tp_ref));
|
||||
break;
|
||||
|
||||
case TPPTtpduin:
|
||||
case TPPTtpduout:
|
||||
tp->tpt_arg2 = arg4;
|
||||
bcopy((caddr_t)src, (caddr_t)&tp->tpt_tpdu,
|
||||
(unsigned)MIN((int)len, sizeof(struct tp_Trace)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* TPPT */
|
||||
@@ -1,196 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_trace.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_trace.h,v 1.3 1994/08/21 06:14:32 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_TRACE_H_
|
||||
#define _NETISO_TP_TRACE_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_trace.h,v 1.3 1994/08/21 06:14:32 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_trace.h,v $
|
||||
*
|
||||
*
|
||||
* Definitions needed for the protocol trace mechanism.
|
||||
*/
|
||||
|
||||
#define TPPTsendack 1
|
||||
#define TPPTgotack 2
|
||||
#define TPPTXack 3
|
||||
#define TPPTgotXack 4
|
||||
#define TPPTack 5
|
||||
#define TPPTindicate 6
|
||||
#define TPPTusrreq 7
|
||||
#define TPPTmisc 8
|
||||
#define TPPTpcb 9
|
||||
#define TPPTref 10
|
||||
#define TPPTtpduin 11
|
||||
#define TPPTparam 12
|
||||
#define TPPTertpdu 13
|
||||
#define TPPTdriver 14
|
||||
#define TPPTtpduout 15
|
||||
|
||||
#include <netiso/tp_pcb.h>
|
||||
|
||||
/* this #if is to avoid lint */
|
||||
|
||||
#if defined(TP_TRACEFILE)||!defined(KERNEL)
|
||||
|
||||
#include <netiso/tp_tpdu.h>
|
||||
|
||||
#define TPTRACE_STRLEN 50
|
||||
|
||||
|
||||
/* for packet tracing */
|
||||
struct tp_timeval {
|
||||
SeqNum tptv_seq;
|
||||
u_int tptv_kind;
|
||||
u_int tptv_window;
|
||||
u_int tptv_size;
|
||||
};
|
||||
|
||||
struct tp_Trace {
|
||||
u_int tpt_event;
|
||||
u_int tpt_arg;
|
||||
u_int tpt_arg2;
|
||||
int tpt_tseq;
|
||||
struct timeval tpt_time;
|
||||
union {
|
||||
struct inpcb tpt_Inpcb; /* protocol control block */
|
||||
struct tp_ref tpt_Ref; /* ref part of pcb */
|
||||
struct tpdu tpt_Tpdu; /* header*/
|
||||
struct tp_refinfo tpt_Param; /* ?? bytes, make sure < 128??*/
|
||||
struct tp_timeval tpt_Time;
|
||||
struct {
|
||||
u_int tptm_2;
|
||||
u_int tptm_3;
|
||||
u_int tptm_4;
|
||||
u_int tptm_5;
|
||||
char tpt_Str[TPTRACE_STRLEN];
|
||||
u_int tptm_1;
|
||||
} tptmisc;
|
||||
u_char tpt_Ertpdu; /* use rest of structure */
|
||||
} tpt_stuff;
|
||||
};
|
||||
#define tpt_inpcb tpt_stuff.tpt_Inpcb
|
||||
#define tpt_pcb tpt_stuff.tpt_Pcb
|
||||
#define tpt_ref tpt_stuff.tpt_Ref
|
||||
#define tpt_tpdu tpt_stuff.tpt_Tpdu
|
||||
#define tpt_param tpt_stuff.tpt_Param
|
||||
#define tpt_ertpdu tpt_stuff.tpt_Ertpdu
|
||||
#define tpt_str tpt_stuff.tptmisc.tpt_Str
|
||||
#define tpt_m1 tpt_stuff.tptmisc.tptm_1
|
||||
#define tpt_m2 tpt_stuff.tptmisc.tptm_2
|
||||
#define tpt_m3 tpt_stuff.tptmisc.tptm_3
|
||||
#define tpt_m4 tpt_stuff.tptmisc.tptm_4
|
||||
#define tpt_m5 tpt_stuff.tptmisc.tptm_5
|
||||
|
||||
#define tpt_seq tpt_stuff.tpt_Time.tptv_seq
|
||||
#define tpt_kind tpt_stuff.tpt_Time.tptv_kind
|
||||
#define tpt_window tpt_stuff.tpt_Time.tptv_window
|
||||
#define tpt_size tpt_stuff.tpt_Time.tptv_size
|
||||
|
||||
#endif /* defined(TP_TRACEFILE)||!defined(KERNEL) */
|
||||
|
||||
|
||||
#ifdef TPPT
|
||||
|
||||
#define TPTRACEN 300
|
||||
|
||||
#define tptrace(A,B,C,D,E,F) \
|
||||
tpTrace((struct tp_pcb *)0,\
|
||||
(u_int)(A),(u_int)(B),(u_int)(C),(u_int)(D),(u_int)(E),(u_int)(F))
|
||||
|
||||
#define tptraceTPCB(A,B,C,D,E,F) \
|
||||
tpTrace(tpcb,\
|
||||
(u_int)(A),(u_int)(B),(u_int)(C),(u_int)(D),(u_int)(E),(u_int)(F))
|
||||
|
||||
extern void tpTrace();
|
||||
extern struct tp_Trace tp_Trace[];
|
||||
extern u_char tp_traceflags[];
|
||||
int tp_Tracen = 0;
|
||||
|
||||
#define IFTRACE(ascii)\
|
||||
if(tp_traceflags[ascii]) {
|
||||
/*
|
||||
* for some reason lint complains about tp_param being undefined no
|
||||
* matter where or how many times I define it.
|
||||
*/
|
||||
#define ENDTRACE }
|
||||
|
||||
|
||||
#else /* TPPT */
|
||||
|
||||
/***********************************************
|
||||
* NO TPPT TRACE STUFF
|
||||
**********************************************/
|
||||
#define TPTRACEN 1
|
||||
|
||||
#define tptrace(A,B,C,D,E,F) 0
|
||||
#define tptraceTPCB(A,B,C,D,E,F) 0
|
||||
|
||||
#define IFTRACE(ascii) if (0) {
|
||||
#define ENDTRACE }
|
||||
|
||||
#endif /* TPPT */
|
||||
|
||||
#endif
|
||||
@@ -1,163 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_user.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_user.h,v 1.3 1994/08/21 06:14:32 paul Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TP_USER_H_
|
||||
#define _NETISO_TP_USER_H_
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_user.h,v 1.3 1994/08/21 06:14:32 paul Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_user.h,v $
|
||||
*
|
||||
* These are the values a real-live user ;-) needs.
|
||||
*/
|
||||
|
||||
#ifndef _TYPES_
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
struct tp_conn_param {
|
||||
/* PER CONNECTION parameters */
|
||||
short p_Nretrans;
|
||||
short p_dr_ticks;
|
||||
|
||||
short p_cc_ticks;
|
||||
short p_dt_ticks;
|
||||
|
||||
short p_x_ticks;
|
||||
short p_cr_ticks;
|
||||
|
||||
short p_keepalive_ticks;
|
||||
short p_sendack_ticks;
|
||||
|
||||
short p_ref_ticks;
|
||||
short p_inact_ticks;
|
||||
|
||||
short p_ptpdusize; /* preferred tpdusize/128 */
|
||||
short p_winsize;
|
||||
|
||||
u_char p_tpdusize; /* log 2 of size */
|
||||
|
||||
u_char p_ack_strat; /* see comments in tp_pcb.h */
|
||||
u_char p_rx_strat; /* see comments in tp_pcb.h */
|
||||
u_char p_class; /* class bitmask */
|
||||
u_char p_xtd_format;
|
||||
u_char p_xpd_service;
|
||||
u_char p_use_checksum;
|
||||
u_char p_use_nxpd; /* netwk expedited data: not implemented */
|
||||
u_char p_use_rcc; /* receipt confirmation: not implemented */
|
||||
u_char p_use_efc; /* explicit flow control: not implemented */
|
||||
u_char p_no_disc_indications; /* don't deliver indic on disc */
|
||||
u_char p_dont_change_params; /* use these params as they are */
|
||||
u_char p_netservice;
|
||||
u_char p_version; /* only here for checking */
|
||||
};
|
||||
|
||||
/*
|
||||
* These sockopt level definitions should be considered for socket.h
|
||||
*/
|
||||
#define SOL_TRANSPORT 0xfffe
|
||||
#define SOL_NETWORK 0xfffd
|
||||
|
||||
/* get/set socket opt commands */
|
||||
#define TPACK_WINDOW 0x0 /* ack only on full window */
|
||||
#define TPACK_EACH 0x1 /* ack every packet */
|
||||
|
||||
#define TPRX_USE_CW 0x8 /* use congestion window transmit */
|
||||
#define TPRX_EACH 0x4 /* retrans each packet of a set */
|
||||
#define TPRX_FASTSTART 0x1 /* don't use slow start */
|
||||
|
||||
#define TPOPT_INTERCEPT 0x200
|
||||
#define TPOPT_FLAGS 0x300
|
||||
#define TPOPT_CONN_DATA 0x400
|
||||
#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_DISC_REASON 0xe00
|
||||
|
||||
struct tp_disc_reason {
|
||||
struct cmsghdr dr_hdr;
|
||||
u_int dr_reason;
|
||||
};
|
||||
|
||||
/*
|
||||
***********************flags**********************************
|
||||
*/
|
||||
|
||||
/* read only flags */
|
||||
#define TPFLAG_NLQOS_PDN (u_char)0x01
|
||||
#define TPFLAG_PEER_ON_SAMENET (u_char)0x02
|
||||
#define TPFLAG_GENERAL_ADDR (u_char)0x04 /* bound to wildcard addr */
|
||||
|
||||
|
||||
/*
|
||||
***********************end flags******************************
|
||||
*/
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,758 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tp_usrreq.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tp_usrreq.c,v 1.3 1995/04/26 21:32:42 pst Exp $
|
||||
*/
|
||||
|
||||
/***********************************************************
|
||||
Copyright IBM Corporation 1987
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of IBM not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
||||
*/
|
||||
/*
|
||||
* ARGO TP
|
||||
*
|
||||
* $Header: /home/ncvs/src/sys/netiso/tp_usrreq.c,v 1.3 1995/04/26 21:32:42 pst Exp $
|
||||
* $Source: /home/ncvs/src/sys/netiso/tp_usrreq.c,v $
|
||||
*
|
||||
* 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
|
||||
* wholly here.
|
||||
* tp_rcvoob() and tp_sendoob() are contained here and called by tp_usrreq().
|
||||
*/
|
||||
|
||||
#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>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <netiso/tp_param.h>
|
||||
#include <netiso/tp_timer.h>
|
||||
#include <netiso/tp_stat.h>
|
||||
#include <netiso/tp_seq.h>
|
||||
#include <netiso/tp_ip.h>
|
||||
#include <netiso/tp_pcb.h>
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/tp_trace.h>
|
||||
#include <netiso/tp_meas.h>
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_errno.h>
|
||||
|
||||
int tp_attach(), tp_driver(), tp_pcbbind();
|
||||
int TNew;
|
||||
int TPNagle1, TPNagle2;
|
||||
struct tp_pcb *tp_listeners, *tp_intercepts;
|
||||
|
||||
#ifdef ARGO_DEBUG
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* anywhere you want to debug...
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* print (str) followed by the control info in the mbufs of an mbuf chain (n)
|
||||
*/
|
||||
void
|
||||
dump_mbuf(n, str)
|
||||
struct mbuf *n;
|
||||
char *str;
|
||||
{
|
||||
struct mbuf *nextrecord;
|
||||
|
||||
printf("dump %s\n", str);
|
||||
|
||||
if (n == MNULL) {
|
||||
printf("EMPTY:\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (n) {
|
||||
nextrecord = n->m_act;
|
||||
printf("RECORD:\n");
|
||||
while (n) {
|
||||
printf("%x : Len %x Data %x A %x Nx %x Tp %x\n",
|
||||
n, n->m_len, n->m_data, n->m_act, n->m_next, n->m_type);
|
||||
#ifdef notdef
|
||||
{
|
||||
register char *p = mtod(n, char *);
|
||||
register int i;
|
||||
|
||||
printf("data: ");
|
||||
for (i = 0; i < n->m_len; i++) {
|
||||
if (i%8 == 0)
|
||||
printf("\n");
|
||||
printf("0x%x ", *(p+i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif /* notdef */
|
||||
if (n->m_next == n) {
|
||||
printf("LOOP!\n");
|
||||
return;
|
||||
}
|
||||
n = n->m_next;
|
||||
}
|
||||
n = nextrecord;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#endif /* ARGO_DEBUG */
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_usrreq(), PRU_RCVOOB
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Copy data from the expedited data socket buffer into
|
||||
* the pre-allocated mbuf m.
|
||||
* There is an isomorphism between XPD TPDUs and expedited data TSDUs.
|
||||
* XPD tpdus are limited to 16 bytes of data so they fit in one mbuf.
|
||||
* RETURN VALUE:
|
||||
* EINVAL if debugging is on and a disaster has occurred
|
||||
* ENOTCONN if the socket isn't connected
|
||||
* EWOULDBLOCK if the socket is in non-blocking mode and there's no
|
||||
* xpd data in the buffer
|
||||
* E* whatever is returned from the fsm.
|
||||
*/
|
||||
tp_rcvoob(tpcb, so, m, outflags, inflags)
|
||||
struct tp_pcb *tpcb;
|
||||
register struct socket *so;
|
||||
register struct mbuf *m;
|
||||
int *outflags;
|
||||
int inflags;
|
||||
{
|
||||
register struct mbuf *n;
|
||||
register struct sockbuf *sb = &so->so_rcv;
|
||||
struct tp_event E;
|
||||
int error = 0;
|
||||
register struct mbuf **nn;
|
||||
|
||||
IFDEBUG(D_XPD)
|
||||
printf("PRU_RCVOOB, sostate 0x%x\n", so->so_state);
|
||||
ENDDEBUG
|
||||
|
||||
/* if you use soreceive */
|
||||
if (m == MNULL)
|
||||
return ENOBUFS;
|
||||
|
||||
restart:
|
||||
if ((((so->so_state & SS_ISCONNECTED) == 0)
|
||||
|| (so->so_state & SS_ISDISCONNECTING) != 0) &&
|
||||
(so->so_proto->pr_flags & PR_CONNREQUIRED)) {
|
||||
return ENOTCONN;
|
||||
}
|
||||
|
||||
/* Take the first mbuf off the chain.
|
||||
* Each XPD TPDU gives you a complete TSDU so the chains don't get
|
||||
* coalesced, but one TSDU may span several mbufs.
|
||||
* Nevertheless, since n should have a most 16 bytes, it
|
||||
* will fit into m. (size was checked in tp_input() )
|
||||
*/
|
||||
|
||||
/*
|
||||
* Code for excision of OOB data should be added to
|
||||
* uipc_socket2.c (like sbappend).
|
||||
*/
|
||||
|
||||
sblock(sb, M_WAITOK);
|
||||
for (nn = &sb->sb_mb; n = *nn; nn = &n->m_act)
|
||||
if (n->m_type == MT_OOBDATA)
|
||||
break;
|
||||
|
||||
if (n == 0) {
|
||||
IFDEBUG(D_XPD)
|
||||
printf("RCVOOB: empty queue!\n");
|
||||
ENDDEBUG
|
||||
sbunlock(sb);
|
||||
if (so->so_state & SS_NBIO) {
|
||||
return EWOULDBLOCK;
|
||||
}
|
||||
sbwait(sb);
|
||||
goto restart;
|
||||
}
|
||||
m->m_len = 0;
|
||||
|
||||
/* Assuming at most one xpd tpdu is in the buffer at once */
|
||||
while (n != MNULL) {
|
||||
m->m_len += n->m_len;
|
||||
bcopy(mtod(n, caddr_t), mtod(m, caddr_t), (unsigned)n->m_len);
|
||||
m->m_data += n->m_len; /* so mtod() in bcopy() above gives right addr */
|
||||
n = n->m_next;
|
||||
}
|
||||
m->m_data = m->m_dat;
|
||||
m->m_flags |= M_EOR;
|
||||
|
||||
IFDEBUG(D_XPD)
|
||||
printf("tp_rcvoob: xpdlen 0x%x\n", m->m_len);
|
||||
dump_mbuf(so->so_rcv.sb_mb, "RCVOOB: Rcv socketbuf");
|
||||
dump_mbuf(sb->sb_mb, "RCVOOB: Xrcv socketbuf");
|
||||
ENDDEBUG
|
||||
|
||||
if ((inflags & MSG_PEEK) == 0) {
|
||||
n = *nn;
|
||||
*nn = n->m_act;
|
||||
for (; n; n = m_free(n))
|
||||
sbfree(sb, n);
|
||||
}
|
||||
|
||||
release:
|
||||
sbunlock(sb);
|
||||
|
||||
IFTRACE(D_XPD)
|
||||
tptraceTPCB(TPPTmisc, "PRU_RCVOOB @ release sb_cc m_len",
|
||||
tpcb->tp_Xrcv.sb_cc, m->m_len, 0, 0);
|
||||
ENDTRACE
|
||||
if (error == 0)
|
||||
error = DoEvent(T_USR_Xrcvd);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* tp_usrreq(), PRU_SENDOOB
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Send what's in the mbuf chain (m) as an XPD TPDU.
|
||||
* The mbuf may not contain more then 16 bytes of data.
|
||||
* XPD TSDUs aren't segmented, so they translate into
|
||||
* exactly one XPD TPDU, with EOT bit set.
|
||||
* RETURN VALUE:
|
||||
* EWOULDBLOCK if socket is in non-blocking mode and the previous
|
||||
* xpd data haven't been acked yet.
|
||||
* EMSGSIZE if trying to send > max-xpd bytes (16)
|
||||
* ENOBUFS if ran out of mbufs
|
||||
*/
|
||||
tp_sendoob(tpcb, so, xdata, outflags)
|
||||
struct tp_pcb *tpcb;
|
||||
register struct socket *so;
|
||||
register struct mbuf *xdata;
|
||||
int *outflags; /* not used */
|
||||
{
|
||||
/*
|
||||
* Each mbuf chain represents a sequence # in the XPD seq space.
|
||||
* The first one in the queue has sequence # tp_Xuna.
|
||||
* When we add to the XPD queue, we stuff a zero-length
|
||||
* mbuf (mark) into the DATA queue, with its sequence number in m_next
|
||||
* to be assigned to this XPD tpdu, so data xfer can stop
|
||||
* when it reaches the zero-length mbuf if this XPD TPDU hasn't
|
||||
* yet been acknowledged.
|
||||
*/
|
||||
register struct sockbuf *sb = &(tpcb->tp_Xsnd);
|
||||
register struct mbuf *xmark;
|
||||
register int len=0;
|
||||
struct tp_event E;
|
||||
|
||||
IFDEBUG(D_XPD)
|
||||
printf("tp_sendoob:");
|
||||
if (xdata)
|
||||
printf("xdata len 0x%x\n", xdata->m_len);
|
||||
ENDDEBUG
|
||||
/* DO NOT LOCK the Xsnd buffer!!!! You can have at MOST one
|
||||
* socket buf locked at any time!!! (otherwise you might
|
||||
* sleep() in sblock() w/ a signal pending and cause the
|
||||
* system call to be aborted w/ a locked socketbuf, which
|
||||
* is a problem. So the so_snd buffer lock
|
||||
* (done in sosend()) serves as the lock for Xpd.
|
||||
*/
|
||||
if (sb->sb_mb) { /* Anything already in eXpedited data sockbuf? */
|
||||
if (so->so_state & SS_NBIO) {
|
||||
return EWOULDBLOCK;
|
||||
}
|
||||
while (sb->sb_mb) {
|
||||
sbunlock(&so->so_snd); /* already locked by sosend */
|
||||
sbwait(&so->so_snd);
|
||||
sblock(&so->so_snd, M_WAITOK); /* sosend will unlock on return */
|
||||
}
|
||||
}
|
||||
|
||||
if (xdata == (struct mbuf *)0) {
|
||||
/* empty xpd packet */
|
||||
MGETHDR(xdata, M_WAIT, MT_OOBDATA);
|
||||
if (xdata == NULL) {
|
||||
return ENOBUFS;
|
||||
}
|
||||
xdata->m_len = 0;
|
||||
xdata->m_pkthdr.len = 0;
|
||||
}
|
||||
IFDEBUG(D_XPD)
|
||||
printf("tp_sendoob 1:");
|
||||
if (xdata)
|
||||
printf("xdata len 0x%x\n", xdata->m_len);
|
||||
ENDDEBUG
|
||||
xmark = xdata; /* temporary use of variable xmark */
|
||||
while (xmark) {
|
||||
len += xmark->m_len;
|
||||
xmark = xmark->m_next;
|
||||
}
|
||||
if (len > TP_MAX_XPD_DATA) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
IFDEBUG(D_XPD)
|
||||
printf("tp_sendoob 2:");
|
||||
if (xdata)
|
||||
printf("xdata len 0x%x\n", len);
|
||||
ENDDEBUG
|
||||
|
||||
|
||||
IFTRACE(D_XPD)
|
||||
tptraceTPCB(TPPTmisc, "XPD mark m_next ", xdata->m_next, 0, 0, 0);
|
||||
ENDTRACE
|
||||
|
||||
sbappendrecord(sb, xdata);
|
||||
|
||||
IFDEBUG(D_XPD)
|
||||
printf("tp_sendoob len 0x%x\n", len);
|
||||
dump_mbuf(so->so_snd.sb_mb, "XPD request Regular sndbuf:");
|
||||
dump_mbuf(tpcb->tp_Xsnd.sb_mb, "XPD request Xsndbuf:");
|
||||
ENDDEBUG
|
||||
return DoEvent(T_XPD_req);
|
||||
}
|
||||
|
||||
/*
|
||||
* CALLED FROM:
|
||||
* the socket routines
|
||||
* FUNCTION and ARGUMENTS:
|
||||
* Handles all "user requests" except the [gs]ockopts() requests.
|
||||
* The argument (req) is the request type (PRU*),
|
||||
* (m) is an mbuf chain, generally used for send and
|
||||
* receive type requests only.
|
||||
* (nam) is used for addresses usually, in particular for the bind request.
|
||||
*
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
ProtoHook
|
||||
tp_usrreq(so, req, m, nam, controlp)
|
||||
struct socket *so;
|
||||
u_int req;
|
||||
struct mbuf *m, *nam, *controlp;
|
||||
{
|
||||
register struct tp_pcb *tpcb = sototpcb(so);
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
int flags, *outflags = &flags;
|
||||
u_long eotsdu = 0;
|
||||
struct tp_event E;
|
||||
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("usrreq(0x%x,%d,0x%x,0x%x,0x%x)\n",so,req,m,nam,outflags);
|
||||
if (so->so_error)
|
||||
printf("WARNING!!! so->so_error is 0x%x\n", so->so_error);
|
||||
ENDDEBUG
|
||||
IFTRACE(D_REQUEST)
|
||||
tptraceTPCB(TPPTusrreq, "req so m state [", req, so, m,
|
||||
tpcb?tpcb->tp_state:0);
|
||||
ENDTRACE
|
||||
|
||||
if ((u_int)tpcb == 0 && req != PRU_ATTACH) {
|
||||
IFTRACE(D_REQUEST)
|
||||
tptraceTPCB(TPPTusrreq, "req failed NO TPCB[", 0, 0, 0, 0);
|
||||
ENDTRACE
|
||||
splx(s);
|
||||
return ENOTCONN;
|
||||
}
|
||||
|
||||
switch (req) {
|
||||
|
||||
case PRU_ATTACH:
|
||||
if (tpcb) {
|
||||
error = EISCONN;
|
||||
} 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 || 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;
|
||||
} /* else DROP THROUGH */
|
||||
|
||||
case PRU_DETACH: /* called from close() */
|
||||
/* called only after disconnect was called */
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
case PRU_SHUTDOWN:
|
||||
/* recv end may have been released; local credit might be zero */
|
||||
case PRU_DISCONNECT:
|
||||
E.ATTR(T_DISC_req).e_reason = E_TP_NORMAL_DISC;
|
||||
error = DoEvent(T_DISC_req);
|
||||
break;
|
||||
|
||||
case PRU_BIND:
|
||||
error = tp_pcbbind(tpcb, nam);
|
||||
break;
|
||||
|
||||
case PRU_LISTEN:
|
||||
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;
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case PRU_CONNECT2:
|
||||
error = EOPNOTSUPP; /* for unix domain sockets */
|
||||
break;
|
||||
|
||||
case PRU_CONNECT:
|
||||
IFTRACE(D_CONN)
|
||||
tptraceTPCB(TPPTmisc,
|
||||
"PRU_CONNECT: so 0x%x *SHORT_LSUFXP(tpcb) 0x%x lsuflen 0x%x, class 0x%x",
|
||||
tpcb->tp_sock, *SHORT_LSUFXP(tpcb), tpcb->tp_lsuffixlen,
|
||||
tpcb->tp_class);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_CONN)
|
||||
printf("PRU_CONNECT: so *SHORT_LSUFXP(tpcb) 0x%x lsuflen 0x%x, class 0x%x",
|
||||
tpcb->tp_sock, *SHORT_LSUFXP(tpcb), tpcb->tp_lsuffixlen,
|
||||
tpcb->tp_class);
|
||||
ENDDEBUG
|
||||
if (tpcb->tp_lsuffixlen == 0) {
|
||||
if (error = tp_pcbbind(tpcb, MNULL)) {
|
||||
IFDEBUG(D_CONN)
|
||||
printf("pcbbind returns error 0x%x\n", error);
|
||||
ENDDEBUG
|
||||
break;
|
||||
}
|
||||
}
|
||||
IFDEBUG(D_CONN)
|
||||
printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
|
||||
dump_buf(tpcb->tp_npcb, 16);
|
||||
ENDDEBUG
|
||||
if (error = tp_route_to(nam, tpcb, /* channel */0))
|
||||
break;
|
||||
IFDEBUG(D_CONN)
|
||||
printf(
|
||||
"PRU_CONNECT after tpcb 0x%x so 0x%x npcb 0x%x flags 0x%x\n",
|
||||
tpcb, so, tpcb->tp_npcb, tpcb->tp_flags);
|
||||
printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
|
||||
dump_buf(tpcb->tp_npcb, 16);
|
||||
ENDDEBUG
|
||||
if (tpcb->tp_fsuffixlen == 0) {
|
||||
/* didn't set peer extended suffix */
|
||||
(tpcb->tp_nlproto->nlp_getsufx)(tpcb->tp_npcb, &tpcb->tp_fsuffixlen,
|
||||
tpcb->tp_fsuffix, TP_FOREIGN);
|
||||
}
|
||||
if (tpcb->tp_state == TP_CLOSED) {
|
||||
soisconnecting(so);
|
||||
error = DoEvent(T_CONN_req);
|
||||
} else {
|
||||
(tpcb->tp_nlproto->nlp_pcbdisc)(tpcb->tp_npcb);
|
||||
error = EISCONN;
|
||||
}
|
||||
IFPERF(tpcb)
|
||||
u_int lsufx, fsufx;
|
||||
lsufx = *(u_short *)(tpcb->tp_lsuffix);
|
||||
fsufx = *(u_short *)(tpcb->tp_fsuffix);
|
||||
|
||||
tpmeas(tpcb->tp_lref,
|
||||
TPtime_open | (tpcb->tp_xtd_format << 4),
|
||||
&time, lsufx, fsufx, tpcb->tp_fref);
|
||||
ENDPERF
|
||||
break;
|
||||
|
||||
case PRU_ACCEPT:
|
||||
(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);
|
||||
ENDDEBUG
|
||||
IFPERF(tpcb)
|
||||
u_int lsufx, fsufx;
|
||||
lsufx = *(u_short *)(tpcb->tp_lsuffix);
|
||||
fsufx = *(u_short *)(tpcb->tp_fsuffix);
|
||||
|
||||
tpmeas(tpcb->tp_lref, TPtime_open,
|
||||
&time, lsufx, fsufx, tpcb->tp_fref);
|
||||
ENDPERF
|
||||
break;
|
||||
|
||||
case PRU_RCVD:
|
||||
if (so->so_state & SS_ISCONFIRMING) {
|
||||
if (tpcb->tp_state == TP_CONFIRMING)
|
||||
error = tp_confirm(tpcb);
|
||||
break;
|
||||
}
|
||||
IFTRACE(D_DATA)
|
||||
tptraceTPCB(TPPTmisc,
|
||||
"RCVD BF: lcredit sent_lcdt cc hiwat \n",
|
||||
tpcb->tp_lcredit, tpcb->tp_sent_lcdt,
|
||||
so->so_rcv.sb_cc, so->so_rcv.sb_hiwat);
|
||||
LOCAL_CREDIT(tpcb);
|
||||
tptraceTPCB(TPPTmisc,
|
||||
"PRU_RCVD AF sbspace lcredit hiwat cc",
|
||||
sbspace(&so->so_rcv), tpcb->tp_lcredit,
|
||||
so->so_rcv.sb_cc, so->so_rcv.sb_hiwat);
|
||||
ENDTRACE
|
||||
IFDEBUG(D_REQUEST)
|
||||
printf("RCVD: cc %d space %d hiwat %d\n",
|
||||
so->so_rcv.sb_cc, sbspace(&so->so_rcv),
|
||||
so->so_rcv.sb_hiwat);
|
||||
ENDDEBUG
|
||||
if (((int)nam) & MSG_OOB)
|
||||
error = DoEvent(T_USR_Xrcvd);
|
||||
else
|
||||
error = DoEvent(T_USR_rcvd);
|
||||
break;
|
||||
|
||||
case PRU_RCVOOB:
|
||||
if ((so->so_state & SS_ISCONNECTED) == 0) {
|
||||
error = ENOTCONN;
|
||||
break;
|
||||
}
|
||||
if (! tpcb->tp_xpd_service) {
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
/* kludge - nam is really flags here */
|
||||
error = tp_rcvoob(tpcb, so, m, outflags, (int)nam);
|
||||
break;
|
||||
|
||||
case PRU_SEND:
|
||||
case PRU_SENDOOB:
|
||||
if (controlp) {
|
||||
error = tp_snd_control(controlp, so, &m);
|
||||
controlp = NULL;
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
if ((so->so_state & SS_ISCONFIRMING) &&
|
||||
(tpcb->tp_state == TP_CONFIRMING) &&
|
||||
(error = tp_confirm(tpcb)))
|
||||
break;
|
||||
if (req == PRU_SENDOOB) {
|
||||
error = (tpcb->tp_xpd_service == 0) ?
|
||||
EOPNOTSUPP : tp_sendoob(tpcb, so, m, outflags);
|
||||
break;
|
||||
}
|
||||
if (m == 0)
|
||||
break;
|
||||
if (m->m_flags & M_EOR) {
|
||||
eotsdu = 1;
|
||||
m->m_flags &= ~M_EOR;
|
||||
}
|
||||
if (eotsdu == 0 && m->m_pkthdr.len == 0)
|
||||
break;
|
||||
if (tpcb->tp_state != TP_AKWAIT && tpcb->tp_state != TP_OPEN) {
|
||||
error = ENOTCONN;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* The protocol machine copies mbuf chains,
|
||||
* prepends headers, assigns seq numbers, and
|
||||
* puts the packets on the device.
|
||||
* When they are acked they are removed from the socket buf.
|
||||
*
|
||||
* sosend calls this up until sbspace goes negative.
|
||||
* Sbspace may be made negative by appending this mbuf chain,
|
||||
* possibly by a whole cluster.
|
||||
*/
|
||||
{
|
||||
/*
|
||||
* 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,
|
||||
PStat(tpcb, Nb_from_sess), totlen);
|
||||
ENDPERF
|
||||
IFDEBUG(D_SYSCALL)
|
||||
printf(
|
||||
"PRU_SEND: eot %d before sbappend 0x%x len 0x%x to sb @ 0x%x\n",
|
||||
eotsdu, m, totlen, sb);
|
||||
dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
|
||||
dump_mbuf(m, "m : to be added");
|
||||
ENDDEBUG
|
||||
tp_packetize(tpcb, m, eotsdu);
|
||||
IFDEBUG(D_SYSCALL)
|
||||
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)
|
||||
error = DoEvent(T_DATA_req);
|
||||
IFDEBUG(D_SYSCALL)
|
||||
printf("PRU_SEND: after driver error 0x%x \n",error);
|
||||
printf("so_snd 0x%x cc 0t%d mbcnt 0t%d\n",
|
||||
sb, sb->sb_cc, sb->sb_mbcnt);
|
||||
dump_mbuf(sb->sb_mb, "so_snd.sb_mb after driver");
|
||||
ENDDEBUG
|
||||
}
|
||||
break;
|
||||
|
||||
case PRU_SOCKADDR:
|
||||
(tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_LOCAL);
|
||||
break;
|
||||
|
||||
case PRU_PEERADDR:
|
||||
(tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_FOREIGN);
|
||||
break;
|
||||
|
||||
case PRU_CONTROL:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
|
||||
case PRU_PROTOSEND:
|
||||
case PRU_PROTORCV:
|
||||
case PRU_SENSE:
|
||||
case PRU_SLOWTIMO:
|
||||
case PRU_FASTTIMO:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef ARGO_DEBUG
|
||||
printf("tp_usrreq UNKNOWN PRU %d\n", req);
|
||||
#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 ? tpcb->tp_state : 0);
|
||||
ENDDEBUG
|
||||
IFTRACE(D_REQUEST)
|
||||
tptraceTPCB(TPPTusrreq, "END req so m state [", req, so, m,
|
||||
tpcb ? tpcb->tp_state : 0);
|
||||
ENDTRACE
|
||||
if (controlp) {
|
||||
m_freem(controlp);
|
||||
printf("control data unexpectedly retained in tp_usrreq()");
|
||||
}
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
tp_ltrace(so, uio)
|
||||
struct socket *so;
|
||||
struct uio *uio;
|
||||
{
|
||||
IFTRACE(D_DATA)
|
||||
register struct tp_pcb *tpcb = sototpcb(so);
|
||||
if (tpcb) {
|
||||
tptraceTPCB(TPPTmisc, "sosend so resid iovcnt", so,
|
||||
uio->uio_resid, uio->uio_iovcnt, 0);
|
||||
}
|
||||
ENDTRACE
|
||||
}
|
||||
|
||||
tp_confirm(tpcb)
|
||||
register struct tp_pcb *tpcb;
|
||||
{
|
||||
struct tp_event E;
|
||||
if (tpcb->tp_state == TP_CONFIRMING)
|
||||
return DoEvent(T_ACPT_req);
|
||||
printf("Tp confirm called when not confirming; tpcb 0x%x, state 0x%x\n",
|
||||
tpcb, tpcb->tp_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process control data sent with sendmsg()
|
||||
*/
|
||||
tp_snd_control(m, so, data)
|
||||
struct mbuf *m;
|
||||
struct socket *so;
|
||||
register struct mbuf **data;
|
||||
{
|
||||
register struct cmsghdr *ch;
|
||||
int error = 0;
|
||||
|
||||
if (m && m->m_len) {
|
||||
ch = mtod(m, struct cmsghdr *);
|
||||
m->m_len -= sizeof (*ch);
|
||||
m->m_data += sizeof (*ch);
|
||||
error = tp_ctloutput(PRCO_SETOPT,
|
||||
so, ch->cmsg_level, ch->cmsg_type, &m);
|
||||
if (ch->cmsg_type == TPOPT_DISC_DATA) {
|
||||
if (data && *data) {
|
||||
m_freem(*data);
|
||||
*data = 0;
|
||||
}
|
||||
error = tp_usrreq(so, PRU_DISCONNECT, (struct mbuf *)0,
|
||||
(caddr_t)0, (struct mbuf *)0);
|
||||
}
|
||||
}
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return error;
|
||||
}
|
||||
@@ -1,349 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* @(#)tuba_subr.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tuba_subr.c,v 1.2 1994/08/02 07:51:34 davidg 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
|
||||
*/
|
||||
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>
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* @(#)tuba_table.c 8.2 (Berkeley) 11/15/93
|
||||
* $Id$
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)tuba_table.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tuba_table.h,v 1.2 1994/08/02 07:51:37 davidg Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETISO_TUBA_TABLE_H_
|
||||
#define _NETISO_TUBA_TABLE_H_
|
||||
|
||||
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
|
||||
|
||||
#endif
|
||||
@@ -1,313 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* @(#)tuba_usrreq.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: tuba_usrreq.c,v 1.2 1994/08/02 07:51:38 davidg 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));
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
# @(#)Makefile 5.16 (Berkeley) 4/26/91
|
||||
|
||||
PROG= xebec
|
||||
SRCS= llparse.c llscan.c main.c malloc.c procs.c putdriver.c sets.c xebec.c
|
||||
CFLAGS+= -DDEBUG -traditional
|
||||
NOMAN = noman
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,22 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/debug.h,v 1.1.1.1 1994/05/24 10:07:51 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/debug.h,v $ */
|
||||
|
||||
#define OUT stdout
|
||||
|
||||
extern int debug[128];
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int column;
|
||||
|
||||
#define IFDEBUG(letter) \
|
||||
if(debug['letter']) {
|
||||
#define ENDDEBUG ; (void) fflush(stdout);}
|
||||
|
||||
#else
|
||||
|
||||
#define STAR *
|
||||
#define IFDEBUG(letter) //*beginning of comment*/STAR
|
||||
#define ENDDEBUG STAR/*end of comment*//
|
||||
|
||||
#endif DEBUG
|
||||
|
||||
@@ -1,366 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/llparse.c,v 1.1.1.1 1994/05/24 10:07:51 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/llparse.c,v $ */
|
||||
/*
|
||||
* ************************* NOTICE *******************************
|
||||
* This code is in the public domain. It cannot be copyrighted.
|
||||
* This ll parser was originally written by Keith Thompson for the
|
||||
* University of Wisconsin Crystal project.
|
||||
* It was based on an FMQ lr parser written by Jon Mauney at the
|
||||
* University of Wisconsin.
|
||||
* It was subsequently modified very slightly by Nancy Hall at the
|
||||
* University of Wisconsin for the Crystal project.
|
||||
* ****************************************************************
|
||||
*/
|
||||
#include "xebec.h"
|
||||
#include "llparse.h"
|
||||
#include "main.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#define LLMINACTION -LLINF
|
||||
|
||||
short llparsestack[STACKSIZE];
|
||||
short llstackptr = 0;
|
||||
LLtoken lltoken;
|
||||
|
||||
llparse()
|
||||
{
|
||||
register havetoken = FALSE;
|
||||
register sym;
|
||||
register LLtoken *t = &lltoken;
|
||||
register parseaction;
|
||||
register accepted = FALSE;
|
||||
|
||||
llpushprod(llnprods-1); /* $$$ ::= <start symbol> */
|
||||
|
||||
do {
|
||||
sym = llparsestack[llstackptr];
|
||||
IFDEBUG(L)
|
||||
printf("llparse() top of loop, llstackptr=%d, sym=%d\n",
|
||||
llstackptr, sym);
|
||||
ENDDEBUG
|
||||
|
||||
if(sym < 0) {
|
||||
/* action symbol */
|
||||
if(sym <= LLMINACTION) {
|
||||
for(;sym<=LLMINACTION;sym++) {
|
||||
llaction(1, t); /* calls llfinprod */
|
||||
}
|
||||
llstackptr--;
|
||||
continue;
|
||||
} else { llaction(-sym, t);
|
||||
llstackptr--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(sym < llnterms) {
|
||||
|
||||
/* it's a terminal symbol */
|
||||
|
||||
if(!havetoken) {
|
||||
llgettoken(t);
|
||||
havetoken = TRUE;
|
||||
}
|
||||
|
||||
if(sym == t->llterm) {
|
||||
llpushattr(t->llattrib);
|
||||
llaccept(t);
|
||||
llstackptr--; /* pop terminal */
|
||||
if(t->llterm == llnterms-1) { /* end symbol $$$ */
|
||||
accepted = TRUE;
|
||||
} else {
|
||||
havetoken = FALSE;
|
||||
}
|
||||
} else {
|
||||
llparsererror(t); /* wrong terminal on input */
|
||||
havetoken = FALSE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* non terminal */
|
||||
|
||||
if(!havetoken) {
|
||||
llgettoken(t);
|
||||
havetoken = TRUE;
|
||||
}
|
||||
|
||||
/* consult parse table for new production */
|
||||
parseaction = llfindaction(sym, t->llterm);
|
||||
|
||||
if(parseaction == 0) {
|
||||
/* error entry */
|
||||
llparsererror(t);
|
||||
havetoken = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(llepsilon[parseaction]) {
|
||||
/* epsilon production */
|
||||
if(llepsilonok(t->llterm)) {
|
||||
llstackptr--; /* pop nonterminal */
|
||||
llpushprod(parseaction); /* push rhs of production */
|
||||
} else {
|
||||
llparsererror(t);
|
||||
havetoken = FALSE;
|
||||
}
|
||||
} else {
|
||||
llstackptr--; /* pop nonterminal */
|
||||
llpushprod(parseaction); /* push rhs of production */
|
||||
}
|
||||
} while(!accepted);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
llpushprod(prod) /* recognize production prod - push rhs on stack */
|
||||
short prod;
|
||||
{
|
||||
register start;
|
||||
register length;
|
||||
register count;
|
||||
|
||||
start = llprodindex[prod].llprodstart;
|
||||
length = llprodindex[prod].llprodlength;
|
||||
|
||||
IFDEBUG(L)
|
||||
printf("llpushprod(%d) llstackptr=0x%x(%d), length = 0x%x(%d)\n",
|
||||
prod, llstackptr, llstackptr, length , length);
|
||||
/*
|
||||
dump_parse_stack();
|
||||
*/
|
||||
ENDDEBUG
|
||||
if(llstackptr+length >= STACKSIZE) {
|
||||
fprintf(stderr,"Parse stack overflow. llstackptr=0x%x, length=0x%x\n",
|
||||
llstackptr, length);
|
||||
Exit(-1);
|
||||
}
|
||||
|
||||
|
||||
llsetattr(llprodindex[prod].llprodtlen);
|
||||
|
||||
/* put a marker on the stack to mark beginning of production */
|
||||
if(llparsestack[llstackptr] <= LLMINACTION) {
|
||||
(llparsestack[llstackptr]) --; /* if there's already one there, don't
|
||||
put another on; just let it represent all of
|
||||
the adjacent markers */
|
||||
}
|
||||
else {
|
||||
llstackptr++;
|
||||
llparsestack[llstackptr] = LLMINACTION;
|
||||
}
|
||||
|
||||
for(count=0; count<length; count++) {
|
||||
llstackptr++;
|
||||
llparsestack[llstackptr] = llproductions[start++];
|
||||
}
|
||||
if(llstackptr > STACKSIZE) {
|
||||
fprintf(stderr, "PARSE STACK OVERFLOW! \n"); Exit(-1);
|
||||
Exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
llepsilonok(term)
|
||||
{
|
||||
register ptr;
|
||||
register sym;
|
||||
register pact;
|
||||
register nomore;
|
||||
register rval;
|
||||
|
||||
IFDEBUG(L)
|
||||
printf("llepsilonok() enter\n");
|
||||
ENDDEBUG
|
||||
rval = TRUE;
|
||||
|
||||
ptr = llstackptr;
|
||||
|
||||
do {
|
||||
sym = llparsestack[ptr];
|
||||
|
||||
if(sym < 0) {
|
||||
ptr--;
|
||||
nomore = ptr == 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sym < llnterms) {
|
||||
nomore = TRUE;
|
||||
rval = sym == term;
|
||||
continue;
|
||||
}
|
||||
|
||||
pact = llfindaction(sym, term);
|
||||
|
||||
if(pact == 0) {
|
||||
nomore = TRUE;
|
||||
rval = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(llepsilon[pact] == TRUE) {
|
||||
ptr--;
|
||||
nomore = ptr == 0;
|
||||
}
|
||||
else {
|
||||
nomore = TRUE;
|
||||
}
|
||||
|
||||
} while(!nomore);
|
||||
|
||||
return(rval);
|
||||
}
|
||||
|
||||
|
||||
short llfindaction(sym, term)
|
||||
{
|
||||
register index;
|
||||
|
||||
IFDEBUG(L)
|
||||
printf("llfindaction(sym=%d, term=%d) enter \n", sym, term);
|
||||
ENDDEBUG
|
||||
index = llparseindex[sym];
|
||||
|
||||
while(llparsetable[index].llterm != 0) {
|
||||
if(llparsetable[index].llterm == term) {
|
||||
return(llparsetable[index].llprod);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
llparsererror(token)
|
||||
LLtoken *token;
|
||||
{
|
||||
IFDEBUG(L)
|
||||
fprintf(stderr,"llparsererror() enter\n");
|
||||
prt_token(token);
|
||||
ENDDEBUG
|
||||
|
||||
fprintf(stderr, "Syntax error: ");
|
||||
prt_token(token);
|
||||
dump_buffer();
|
||||
Exit(-1);
|
||||
}
|
||||
|
||||
|
||||
llgettoken(token)
|
||||
LLtoken *token;
|
||||
{
|
||||
llscan(token);
|
||||
token->llstate = NORMAL;
|
||||
IFDEBUG(L)
|
||||
printf("llgettoken(): ");
|
||||
prt_token(token);
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
Attribute support routines
|
||||
|
||||
******************************************************************************/
|
||||
/*
|
||||
** attribute stack
|
||||
**
|
||||
** AttrStack = stack of record
|
||||
** values : array of values;
|
||||
** ptr : index;
|
||||
** end;
|
||||
**
|
||||
*/
|
||||
|
||||
LLattrib llattributes[LLMAXATTR];
|
||||
int llattrtop = 0;
|
||||
|
||||
struct llattr llattrdesc[LLMAXDESC];
|
||||
|
||||
int lldescindex = 1;
|
||||
|
||||
|
||||
llsetattr(n)
|
||||
{
|
||||
register struct llattr *ptr;
|
||||
|
||||
IFDEBUG(L)
|
||||
printf("llsetattr(%d) enter\n",n);
|
||||
ENDDEBUG
|
||||
if(lldescindex >= LLMAXDESC) {
|
||||
fprintf(stdout, "llattribute stack overflow: desc\n");
|
||||
fprintf(stdout,
|
||||
"lldescindex=0x%x, llattrtop=0x%x\n",lldescindex, llattrtop);
|
||||
Exit(-1);
|
||||
}
|
||||
ptr = &llattrdesc[lldescindex];
|
||||
ptr->llabase = &llattributes[llattrtop];
|
||||
ptr->lloldtop = ++llattrtop;
|
||||
ptr->llaindex = 1;
|
||||
ptr->llacnt = n+1; /* the lhs ALWAYS uses an attr; it remains on the
|
||||
stack when the production is recognized */
|
||||
lldescindex++;
|
||||
}
|
||||
|
||||
llpushattr(attr)
|
||||
LLattrib attr;
|
||||
{
|
||||
struct llattr *a;
|
||||
|
||||
IFDEBUG(L)
|
||||
printf("llpushattr() enter\n");
|
||||
ENDDEBUG
|
||||
if(llattrtop + 1 > LLMAXATTR) {
|
||||
fprintf(stderr, "ATTRIBUTE STACK OVERFLOW!\n");
|
||||
Exit(-1);
|
||||
}
|
||||
a = &llattrdesc[lldescindex-1];
|
||||
llattributes[llattrtop++] = attr;
|
||||
a->llaindex++; /* inc count of attrs on the stack for this prod */
|
||||
}
|
||||
|
||||
llfinprod()
|
||||
{
|
||||
IFDEBUG(L)
|
||||
printf("llfinprod() enter\n");
|
||||
ENDDEBUG
|
||||
lldescindex--;
|
||||
llattrtop = llattrdesc[lldescindex].lloldtop;
|
||||
llattrdesc[lldescindex-1].llaindex++; /* lhs-of-prod.attr stays on
|
||||
the stack; it is now one of the rhs attrs of the now-top production
|
||||
on the stack */
|
||||
}
|
||||
|
||||
#ifndef LINT
|
||||
#ifdef DEBUG
|
||||
dump_parse_stack()
|
||||
{
|
||||
int ind;
|
||||
|
||||
printf("PARSE STACK:\n");
|
||||
for(ind=llstackptr; ind>=0; ind--) {
|
||||
printf("%d\t%d\t%s\n",
|
||||
ind, llparsestack[ind],
|
||||
llparsestack[ind]<0? "Action symbol" : llstrings[llparsestack[ind]]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif DEBUG
|
||||
#endif LINT
|
||||
|
||||
prt_token(t)
|
||||
LLtoken *t;
|
||||
{
|
||||
fprintf(stdout, "t at 0x%x\n", t);
|
||||
fprintf(stdout, "t->llterm=0x%x\n", t->llterm); (void) fflush(stdout);
|
||||
fprintf(stdout, "TOK: %s\n", llstrings[t->llterm]);
|
||||
(void) fflush(stdout);
|
||||
#ifdef LINT
|
||||
/* to make lint shut up */
|
||||
fprintf(stdout, "", llnterms, llnsyms, llnprods, llinfinite);
|
||||
#endif LINT
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/llparse.h,v 1.1.1.1 1994/05/24 10:07:50 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/llparse.h,v $ */
|
||||
|
||||
/************************************************************
|
||||
attributes stack garbage
|
||||
************************************************************/
|
||||
|
||||
#define LLMAXATTR 512
|
||||
#define LLMAXDESC 256
|
||||
#define LLATTR /* build an attribute stack */
|
||||
|
||||
/*
|
||||
** attribute stack
|
||||
**
|
||||
** AttrStack = stack of record
|
||||
** values : array of values;
|
||||
** ptr : index;
|
||||
** end;
|
||||
**
|
||||
*/
|
||||
|
||||
typedef union llattrib LLattrib;
|
||||
|
||||
extern LLattrib llattributes[LLMAXATTR];
|
||||
extern int llattrtop;
|
||||
|
||||
extern struct llattr {
|
||||
LLattrib *llabase; /* ptr into the attr stack (llattributes) */
|
||||
int llaindex;/* # attrs on the stack so far for this prod */
|
||||
int llacnt;/* total # ever to go on for this prod */
|
||||
|
||||
int lloldtop;/* when popping this prod, restore stack to here ;
|
||||
one attr will remain on the stack (for the lhs) */
|
||||
} llattrdesc[LLMAXDESC];
|
||||
|
||||
extern int lldescindex;
|
||||
|
||||
/************************************************************
|
||||
attributes stack garbage
|
||||
************************************************************/
|
||||
|
||||
extern struct lltoken {
|
||||
short llterm; /* token number */
|
||||
short llstate; /* inserted deleted normal */
|
||||
LLattrib llattrib;
|
||||
} lltoken;
|
||||
typedef struct lltoken LLtoken;
|
||||
|
||||
/************************************************************
|
||||
constants used in llparse.c
|
||||
************************************************************/
|
||||
|
||||
#define STACKSIZE 500
|
||||
#define MAXCORR 16
|
||||
|
||||
#define NORMAL 0
|
||||
#define DELETE 1
|
||||
#define INSERT 2
|
||||
|
||||
/************************************************************
|
||||
datatypes used to communicate with the parser
|
||||
************************************************************/
|
||||
|
||||
struct llinsert {
|
||||
short llinscost;
|
||||
short llinslength;
|
||||
short llinsert[MAXCORR];
|
||||
};
|
||||
typedef struct llinsert LLinsert;
|
||||
|
||||
extern short llparsestack[];
|
||||
extern short llstackptr;
|
||||
extern short llinfinite;
|
||||
|
||||
/************************************************************
|
||||
variables used to pass information
|
||||
specific to each grammer
|
||||
************************************************************/
|
||||
|
||||
extern short llnterms;
|
||||
extern short llnsyms;
|
||||
extern short llnprods;
|
||||
|
||||
extern char *llefile;
|
||||
|
||||
extern struct llparsetable {
|
||||
short llterm;
|
||||
short llprod;
|
||||
} llparsetable[];
|
||||
|
||||
extern short llparseindex[];
|
||||
|
||||
extern short llepsilon[];
|
||||
|
||||
extern short llproductions[];
|
||||
|
||||
extern struct llprodindex {
|
||||
short llprodstart;
|
||||
short llprodlength;
|
||||
short llprodtlen;
|
||||
} llprodindex[];
|
||||
|
||||
extern struct llcosts {
|
||||
short llinsert;
|
||||
short lldelete;
|
||||
} llcosts[];
|
||||
|
||||
extern struct llstable {
|
||||
short llsstart;
|
||||
short llslength;
|
||||
} llstable[];
|
||||
|
||||
extern short llsspace[];
|
||||
|
||||
extern struct lletable {
|
||||
short llecost;
|
||||
short llelength;
|
||||
short llestart;
|
||||
} lletable[];
|
||||
|
||||
extern long lleindex[];
|
||||
|
||||
extern short llespace[];
|
||||
|
||||
extern char *llstrings[];
|
||||
|
||||
/************************************************************
|
||||
routines defined in llparse.c
|
||||
************************************************************/
|
||||
|
||||
extern llparse();
|
||||
extern llcopye();
|
||||
extern llcopys();
|
||||
extern llcorrector();
|
||||
extern llepsilonok();
|
||||
extern llexpand();
|
||||
extern short llfindaction();
|
||||
extern llgetprefix();
|
||||
extern llgettoken();
|
||||
extern llinsert();
|
||||
extern llinsertsym();
|
||||
extern llinserttokens();
|
||||
extern llparsererror();
|
||||
extern llpushprod();
|
||||
extern llreadetab();
|
||||
@@ -1,430 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/llscan.c,v 1.1.1.1 1994/05/24 10:07:50 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/llscan.c,v $ */
|
||||
/*
|
||||
* ************************* NOTICE *******************************
|
||||
* This code is in the public domain. It cannot be copyrighted.
|
||||
* This scanner was originally written by Keith Thompson for the
|
||||
* University of Wisconsin Crystal project.
|
||||
* It was subsequently modified significantly by Nancy Hall at the
|
||||
* University of Wisconsin for the ARGO project.
|
||||
* ****************************************************************
|
||||
*/
|
||||
#include "xebec.h"
|
||||
#include "llparse.h"
|
||||
|
||||
#include "main.h"
|
||||
#include <stdio.h>
|
||||
#include "procs.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define EOFILE 0x01
|
||||
#define UNUSED 0x02
|
||||
#define IGNORE 0x04
|
||||
#define OPCHAR 0x8
|
||||
#define DIGITS 0x10
|
||||
#define LETTER 0x20
|
||||
|
||||
int chtype[128] = {
|
||||
/* null, soh ^a, stx ^b etx ^c eot ^d enq ^e ack ^f bel ^g */
|
||||
EOFILE, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED,
|
||||
/* bs ^h ht ^i lf ^j vt ^k ff ^l cr ^m so ^n si ^o */
|
||||
UNUSED, IGNORE, IGNORE, UNUSED, IGNORE, IGNORE, UNUSED, UNUSED,
|
||||
/* dle ^p dc1 ^q dc2 ^r dc3 ^s dc4 ^t nak ^u syn ^v etb ^w */
|
||||
UNUSED, UNUSED, UNUSED, UNUSED, EOFILE, UNUSED, UNUSED, UNUSED,
|
||||
/* can ^x em ^y sub ^z esc ^] fs ^\ gs ^} rs ^` us ^/ */
|
||||
UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED,
|
||||
|
||||
/* ! " # $ % & ' */
|
||||
IGNORE, UNUSED, OPCHAR, UNUSED, OPCHAR, UNUSED, OPCHAR, OPCHAR,
|
||||
/* ( ) * + , - . / */
|
||||
OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR,
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
DIGITS, DIGITS, DIGITS, DIGITS, DIGITS, DIGITS, DIGITS, DIGITS,
|
||||
/* 8 9 : ; < = > ? */
|
||||
DIGITS, DIGITS, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR,
|
||||
|
||||
/* @ A B C D E F G */
|
||||
UNUSED, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
|
||||
/* H I J K L M N O */
|
||||
LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
|
||||
/* P Q R S T U V W */
|
||||
LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
|
||||
/* X Y Z [ \ ] ^ _ */
|
||||
LETTER, LETTER, LETTER, OPCHAR, UNUSED, OPCHAR, OPCHAR, LETTER,
|
||||
|
||||
/* ` a b c d e f g */
|
||||
UNUSED, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
|
||||
/* h i j k l m n o */
|
||||
LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
|
||||
/* p q r s t u v w */
|
||||
LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
|
||||
/* x y z { | } ~ del */
|
||||
LETTER, LETTER, LETTER, OPCHAR, UNUSED, OPCHAR, UNUSED, UNUSED
|
||||
};
|
||||
|
||||
|
||||
extern FILE *astringfile;
|
||||
static char *buffptr;
|
||||
static char buffer[2][LINELEN];
|
||||
static int currentbuf = 1;
|
||||
|
||||
#define addbuf(x) *buffptr++ = x
|
||||
|
||||
static int ch = ' ';
|
||||
|
||||
skip()
|
||||
{
|
||||
while((chtype[ch] == IGNORE) ) {
|
||||
ch = getch();
|
||||
}
|
||||
}
|
||||
|
||||
llaccept(t)
|
||||
LLtoken *t;
|
||||
{
|
||||
switch(t->llstate) {
|
||||
case NORMAL:
|
||||
break;
|
||||
case INSERT:
|
||||
fprintf(stderr,"Insert %s\n", llstrings[t->llterm]);
|
||||
break;
|
||||
case DELETE:
|
||||
fprintf(stderr,"Delete %s\n", llstrings[t->llterm]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define TVAL (t->llattrib)
|
||||
|
||||
|
||||
dump_buffer()
|
||||
{
|
||||
register int i;
|
||||
for(i=0; i<20; i++)
|
||||
(void) fputc(buffer[currentbuf][i], stderr);
|
||||
(void) fputc('\n', stderr);
|
||||
(void) fflush(stderr);
|
||||
}
|
||||
|
||||
int iskey(c, buf)
|
||||
char *c;
|
||||
char **buf;
|
||||
{
|
||||
register int i;
|
||||
static struct { char *key_word; int term_type; } keys[] = {
|
||||
{ "SAME", T_SAME },
|
||||
{ "DEFAULT", T_DEFAULT },
|
||||
{ "NULLACTION", T_NULLACTION },
|
||||
{ "STRUCT", T_STRUCT },
|
||||
{ "SYNONYM", T_SYNONYM },
|
||||
{ "TRANSITIONS", T_TRANSITIONS },
|
||||
{ "STATES", T_STATES },
|
||||
{ "EVENTS", T_EVENTS },
|
||||
{ "PCB", T_PCB },
|
||||
{ "INCLUDE", T_INCLUDE },
|
||||
{ "PROTOCOL", T_PROTOCOL },
|
||||
{ 0, 0},
|
||||
};
|
||||
|
||||
for (i = 0; keys[i].key_word ; i++) {
|
||||
if( !strcmp(c, (*buf = keys[i].key_word) ) ) {
|
||||
return ( keys[i].term_type );
|
||||
}
|
||||
}
|
||||
*buf = (char *)0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
getstr(o,c)
|
||||
/* c is the string delimiter
|
||||
* allow the delimiter to be escaped
|
||||
* the messy part: translate $ID to
|
||||
* e->ev_union.ID
|
||||
* where ID is an event with a non-zero obj_struc
|
||||
* need we check for the field???
|
||||
*/
|
||||
char o,c;
|
||||
{
|
||||
register int nested = 1;
|
||||
register int allow_nesting = (o==c)?-1:1;
|
||||
|
||||
IFDEBUG(S)
|
||||
fprintf(stdout,"getstr: ch=%c, delimiters %c %c\n",
|
||||
ch,o, c);
|
||||
fprintf(stdout,"getstr: buffptr 0x%x, currentbuf 0x%x\n",
|
||||
buffptr, currentbuf);
|
||||
ENDDEBUG
|
||||
|
||||
if( ch == c ) nested--;
|
||||
while(nested) {
|
||||
if(ch == '\0') {
|
||||
fprintf(stderr,
|
||||
"Eof inside of a string, delims= %c,%c, nesting %d",c,o, nested);
|
||||
Exit(-1);
|
||||
/* notreached */
|
||||
} else if(ch == '$') {
|
||||
/* might be an attribute */
|
||||
IFDEBUG(S)
|
||||
fprintf(stdout,"getstr: atttribute?\n");
|
||||
ENDDEBUG
|
||||
|
||||
/* assume it's an event */
|
||||
/* addbuf is a macro so this isn't as bad as
|
||||
* it looks
|
||||
* add "e->ev_union."
|
||||
*/
|
||||
if( (ch = getch()) == '$' ) {
|
||||
addbuf('e'); addbuf('-'); addbuf('>');
|
||||
addbuf('e'); addbuf('v'); addbuf('_');
|
||||
addbuf('u'); addbuf('n'); addbuf('i');
|
||||
addbuf('o'); addbuf('n');
|
||||
addbuf('.');
|
||||
AddCurrentEventName(& buffptr);
|
||||
} else {
|
||||
char *obufp = buffptr;
|
||||
|
||||
do {
|
||||
addbuf(ch);
|
||||
ch = getch();
|
||||
} while(chtype[ch] & LETTER);
|
||||
addbuf('\0');
|
||||
if( !strncmp(obufp, synonyms[PCB_SYN],
|
||||
strlen(synonyms[PCB_SYN]) )) {
|
||||
buffptr = obufp;
|
||||
addbuf('p');
|
||||
} else if( !strncmp(obufp, synonyms[EVENT_SYN],
|
||||
strlen(synonyms[EVENT_SYN]))) {
|
||||
buffptr = obufp;
|
||||
addbuf('e');
|
||||
} else {
|
||||
fprintf(stderr, "Unknown synonym %s\n", obufp);
|
||||
Exit(-1);
|
||||
}
|
||||
if(ch == '.') {
|
||||
addbuf('-'); addbuf('>');
|
||||
} else {
|
||||
/* needs to be checked for nesting */
|
||||
goto check;
|
||||
}
|
||||
}
|
||||
/* end of attribute handling */
|
||||
goto skip;
|
||||
} else if(ch == '\\') {
|
||||
/* possible escape - this is kludgy beyond belief:
|
||||
* \ is used to escape open and closing delimiters
|
||||
* and '$'
|
||||
* otherwise it's passed through to be compiled by C
|
||||
*/
|
||||
ch = getch();
|
||||
if( (ch != o ) && (ch != c) && (ch != '$') ) {
|
||||
/* may need to handle case where \ is last char in file... */
|
||||
/* don't treat is as escape; not open or close so
|
||||
* don't have to worry about nesting either
|
||||
*/
|
||||
addbuf('\\');
|
||||
}
|
||||
}
|
||||
addbuf(ch);
|
||||
skip:
|
||||
ch = getch();
|
||||
check:
|
||||
if( ch == o ) nested += allow_nesting;
|
||||
else if( ch == c ) nested--;
|
||||
if ( (buffptr - buffer[currentbuf]) > LINELEN) {
|
||||
fprintf(stderr,
|
||||
"%s too long.\n", (o=='{')?"Action":"Predicate"); /*}*/
|
||||
fprintf(stderr,
|
||||
"buffptr, currentbuf 0x%x, 0x%x\n",buffptr,currentbuf );
|
||||
Exit(-1);
|
||||
}
|
||||
IFDEBUG(S)
|
||||
fprintf(stdout,"loop in getstr: ch 0x%x,%c o=%c,c=%c nested=%d\n",
|
||||
ch,ch,o,c,nested);
|
||||
ENDDEBUG
|
||||
}
|
||||
addbuf(ch);
|
||||
addbuf('\0');
|
||||
|
||||
IFDEBUG(S)
|
||||
fprintf(stdout,"exit getstr: got %s\n", buffer[currentbuf]);
|
||||
fprintf(stdout,"exit getstr: buffptr 0x%x, currentbuf 0x%x\n",
|
||||
buffptr, currentbuf);
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
getch()
|
||||
{
|
||||
char c;
|
||||
extern FILE *infile;
|
||||
extern int lineno;
|
||||
|
||||
c = fgetc(infile) ;
|
||||
if (c == '\n') lineno++;
|
||||
if ((int)c == EOF) c = (char)0;
|
||||
if (feof(infile)) c = (char) 0;
|
||||
IFDEBUG(e)
|
||||
fprintf(stdout, "getch: 0x%x\n", c);
|
||||
(void) fputc( c, stdout);
|
||||
fflush(stdout);
|
||||
ENDDEBUG
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
llscan(t)
|
||||
LLtoken *t;
|
||||
{
|
||||
char c;
|
||||
|
||||
t->llstate = NORMAL;
|
||||
|
||||
++currentbuf;
|
||||
currentbuf&=1;
|
||||
again:
|
||||
buffptr = &buffer[currentbuf][0];
|
||||
|
||||
skip();
|
||||
|
||||
switch(chtype[ch]) {
|
||||
|
||||
case EOFILE:
|
||||
t->llterm = T_ENDMARKER;
|
||||
break;
|
||||
|
||||
case UNUSED:
|
||||
fprintf(stderr, "Illegal character in input - 0x%x ignored.", ch);
|
||||
ch = getch();
|
||||
goto again;
|
||||
|
||||
case OPCHAR:
|
||||
|
||||
switch(ch) {
|
||||
|
||||
case '/':
|
||||
/* possible comment : elide ; kludge */
|
||||
IFDEBUG(S)
|
||||
fprintf(stdout, "Comment ch=%c\n", ch);
|
||||
ENDDEBUG
|
||||
c = getch();
|
||||
if (c != '*') {
|
||||
fprintf(stderr,"Syntax error : character(0x%x) ignored", ch);
|
||||
ch = c;
|
||||
goto again;
|
||||
} else {
|
||||
register int state = 2, whatchar=0;
|
||||
static int dfa[3][3] = {
|
||||
/* done seen-star middle */
|
||||
/* star */ { 0, 1, 1 },
|
||||
/* / */ { 0, 0, 2 },
|
||||
/* other */ { 0, 2, 2 }
|
||||
};
|
||||
|
||||
while( state ) {
|
||||
if( (c = getch()) == (char)0)
|
||||
break;
|
||||
whatchar = (c=='*')?0:(c=='/'?1:2);
|
||||
IFDEBUG(S)
|
||||
fprintf(stdout,
|
||||
"comment: whatchar = %d, c = 0x%x,%c, oldstate=%d",
|
||||
whatchar, c,c, state);
|
||||
ENDDEBUG
|
||||
state = dfa[whatchar][state];
|
||||
IFDEBUG(S)
|
||||
fprintf(stdout, ", newstate=%d\n", state);
|
||||
ENDDEBUG
|
||||
}
|
||||
if(state) {
|
||||
fprintf(stderr,
|
||||
"Syntax error: end of file inside a comment");
|
||||
Exit(-1);
|
||||
} else ch = getch();
|
||||
}
|
||||
IFDEBUG(S)
|
||||
fprintf(stdout, "end of comment at 0x%x,%c\n",ch,ch);
|
||||
ENDDEBUG
|
||||
goto again;
|
||||
|
||||
|
||||
case '*':
|
||||
t->llterm = T_STAR;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
t->llterm = T_COMMA;
|
||||
break;
|
||||
|
||||
case ';':
|
||||
t->llterm = T_SEMI;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
t->llterm = T_LANGLE;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
t->llterm = T_EQUAL;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
t->llterm = T_LBRACK;
|
||||
break;
|
||||
|
||||
case ']':
|
||||
t->llterm = T_RBRACK;
|
||||
break;
|
||||
|
||||
#ifdef T_FSTRING
|
||||
case '"':
|
||||
t->llterm = T_FSTRING;
|
||||
addbuf(ch);
|
||||
ch = getch();
|
||||
getstr('"', '"');
|
||||
TVAL.FSTRING.address = stash(buffer[currentbuf]);
|
||||
break;
|
||||
#endif T_FSTRING
|
||||
|
||||
case '(':
|
||||
t->llterm = T_PREDICATE;
|
||||
getstr(ch, ')' );
|
||||
TVAL.PREDICATE.address = buffer[currentbuf];
|
||||
break;
|
||||
|
||||
case '{':
|
||||
t->llterm = T_ACTION;
|
||||
getstr(ch, '}');
|
||||
TVAL.ACTION.address = buffer[currentbuf];
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,"Syntax error : character(0x%x) ignored", ch);
|
||||
ch = getch();
|
||||
goto again;
|
||||
|
||||
}
|
||||
ch = getch();
|
||||
break;
|
||||
|
||||
case LETTER:
|
||||
do {
|
||||
addbuf(ch);
|
||||
ch = getch();
|
||||
} while(chtype[ch] & (LETTER | DIGITS));
|
||||
|
||||
addbuf('\0');
|
||||
|
||||
t->llterm = iskey(buffer[currentbuf], &TVAL.ID.address);
|
||||
if(!t->llterm) {
|
||||
t->llterm = T_ID;
|
||||
TVAL.ID.address = buffer[currentbuf];
|
||||
}
|
||||
IFDEBUG(S)
|
||||
fprintf(stdout, "llscan: id or keyword 0x%x, %s\n",
|
||||
TVAL.ID.address, TVAL.ID.address);
|
||||
ENDDEBUG
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Snark in llscan: chtype=0x%x, ch=0x%x\n",
|
||||
chtype[ch], ch);
|
||||
}
|
||||
}
|
||||
@@ -1,410 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/main.c,v 1.1.1.1 1994/05/24 10:07:49 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/main.c,v $ */
|
||||
/*
|
||||
* TODO:
|
||||
* rewrite the command line stuff altogether - it's kludged beyond
|
||||
* belief (as is the rest of the code...)
|
||||
*
|
||||
* DISCLAIMER DISCLAIMER DISCLAIMER
|
||||
* This code is such a kludge that I don't want to put my name on it.
|
||||
* It was a ridiculously fast hack and needs rewriting.
|
||||
* However it does work...
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include "malloc.h"
|
||||
#include "debug.h"
|
||||
#include "main.h"
|
||||
|
||||
int debug[128];
|
||||
|
||||
int lineno = 1;
|
||||
|
||||
FILE *statefile, *actfile, *eventfile_h, *statevalfile;
|
||||
FILE *infile, *astringfile;
|
||||
char *Transfilename;
|
||||
char *astringfile_name = DEBUGFILE;
|
||||
char *actfile_name = ACTFILE;
|
||||
char *statefile_name = STATEFILE;
|
||||
char *statevalfile_name = STATEVALFILE;
|
||||
char *eventfile_h_name = EVENTFILE_H;
|
||||
int print_trans = 0;
|
||||
int print_protoerrs = 0;
|
||||
int pgoption = 0;
|
||||
char kerneldirname[50] = "\0";
|
||||
|
||||
char protocol[50];
|
||||
|
||||
char *synonyms[] = {
|
||||
"EVENT",
|
||||
"PCB",
|
||||
0
|
||||
};
|
||||
|
||||
usage(a)
|
||||
char *a;
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s <transition file> {-D<debug options>} <other options>\n",
|
||||
a);
|
||||
fprintf(stderr, "\t<other options> is any combination of:\n");
|
||||
fprintf(stderr, "\t\t-A<action file name>\n");
|
||||
fprintf(stderr, "\t\t-E<event file name>\n");
|
||||
fprintf(stderr, "\t\t-S<state file name>\n");
|
||||
fprintf(stderr, "\t\t-I<initial values file name>\n");
|
||||
fprintf(stderr, "\t\t-X<debugging file name>\n");
|
||||
fprintf(stderr, "\t\t-K<directory name>\n");
|
||||
fprintf(stderr,
|
||||
"\tThese names do NOT include the suffices (.c, .h)\n");
|
||||
fprintf(stderr,
|
||||
"\t\t-D<options> to turn on debug options for xebec itself\n");
|
||||
fprintf(stderr, "\t-<nn> for levels of debugging output\n");
|
||||
fprintf(stderr, "\t\t<nn> ranges from 1 to 3, 1 is default(everything)\n");
|
||||
fprintf(stderr, "\t\t-T to print transitions\n");
|
||||
fprintf(stderr, "\t\t-e to print list of combinations of\n");
|
||||
fprintf(stderr, "\t\t\t [event,old_state] that produce protocol errors\n");
|
||||
fprintf(stderr, "\t\t-g include profiling code in driver\n");
|
||||
Exit(-1);
|
||||
}
|
||||
|
||||
openfiles(proto)
|
||||
register char *proto;
|
||||
{
|
||||
register char *junk;
|
||||
register int lenp = strlen(proto);
|
||||
|
||||
IFDEBUG(b)
|
||||
fprintf(OUT, "openfiles %s\n",proto);
|
||||
ENDDEBUG
|
||||
|
||||
#define HEADER Header
|
||||
#define SOURCE Source
|
||||
#define DOIT(X)\
|
||||
/* GAG */\
|
||||
junk = Malloc( 2 + lenp + strlen(X/**/_name) );\
|
||||
(void) sprintf(junk, "%s_", proto);\
|
||||
X/**/_name = strcat(junk, X/**/_name);\
|
||||
X = fopen(X/**/_name, "w");\
|
||||
if((X)==(FILE *)0)\
|
||||
{ fprintf(stderr,"Open failed: %s\n", "X"); Exit(-1); }\
|
||||
fprintf(X, "/* %cHeader%c */\n",'$', '$' );\
|
||||
fprintf(X, "/* %cSource%c */\n",'$', '$' );
|
||||
|
||||
DOIT(eventfile_h);
|
||||
|
||||
IFDEBUG(X)
|
||||
#ifdef DEBUG
|
||||
DOIT(astringfile);
|
||||
#endif DEBUG
|
||||
fprintf(astringfile,
|
||||
"#ifndef _NFILE\n#include <stdio.h>\n#endif _NFILE\n" );
|
||||
ENDDEBUG
|
||||
|
||||
DOIT(statevalfile);
|
||||
DOIT(statefile);
|
||||
DOIT(actfile);
|
||||
fprintf(actfile,
|
||||
"#ifndef lint\nstatic char *rcsid = \"$Header/**/$\";\n#endif lint\n");
|
||||
|
||||
if(pgoption)
|
||||
putdriver(actfile, 15);
|
||||
else
|
||||
putdriver(actfile, 14);
|
||||
|
||||
FakeFilename(actfile, Transfilename, lineno);
|
||||
putdriver(actfile, 1);
|
||||
FakeFilename(actfile, Transfilename, lineno);
|
||||
putdriver(actfile, 12);
|
||||
fprintf(actfile, "#include \"%s%s\"\n", kerneldirname, statevalfile_name);
|
||||
FakeFilename(actfile, Transfilename, lineno);
|
||||
putdriver(actfile, 2);
|
||||
|
||||
initsets(eventfile_h, statefile);
|
||||
}
|
||||
|
||||
includecode(file, f)
|
||||
FILE *file;
|
||||
register char *f;
|
||||
{
|
||||
register int count=1;
|
||||
static char o='{';
|
||||
static char c='}';
|
||||
register char *g;
|
||||
|
||||
IFDEBUG(a)
|
||||
fprintf(stdout, "including: %s, f=0x%x", f,f);
|
||||
ENDDEBUG
|
||||
g = ++f;
|
||||
while(count>0) {
|
||||
if(*g == o) count++;
|
||||
if(*g == c) count--;
|
||||
g++;
|
||||
}
|
||||
*(--g) = '\0';
|
||||
IFDEBUG(a)
|
||||
fprintf(stdout, "derived: %s", f);
|
||||
ENDDEBUG
|
||||
fprintf(file, "%s", f);
|
||||
FakeFilename(file, Transfilename, lineno);
|
||||
}
|
||||
|
||||
putincludes()
|
||||
{
|
||||
FakeFilename(actfile, Transfilename, lineno);
|
||||
fprintf(actfile, "\n#include \"%s%s\"\n", kerneldirname, eventfile_h_name);
|
||||
IFDEBUG(X)
|
||||
if( !debug['K'] )
|
||||
fprintf(actfile, "\n#include \"%s\"\n", astringfile_name);
|
||||
/* not in kernel mode */
|
||||
ENDDEBUG
|
||||
FakeFilename(actfile, Transfilename, lineno);
|
||||
}
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register int i = 2;
|
||||
extern char *strcpy();
|
||||
int start, finish;
|
||||
extern int FirstEventAttribute;
|
||||
extern int Nevents, Nstates;
|
||||
|
||||
start = time(0);
|
||||
if(argc < 2) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
IFDEBUG(a)
|
||||
fprintf(stdout, "infile = %s\n",argv[1]);
|
||||
ENDDEBUG
|
||||
Transfilename = argv[1];
|
||||
infile = fopen(argv[1], "r");
|
||||
|
||||
if(argc > 2) while(i < argc) {
|
||||
register int j=0;
|
||||
char c;
|
||||
char *name;
|
||||
|
||||
if(argv[i][j] == '-') j++;
|
||||
switch(c = argv[i][j]) {
|
||||
|
||||
/* GROT */
|
||||
case 'A':
|
||||
name = &argv[i][++j];
|
||||
actfile_name = Malloc( strlen(name)+4);
|
||||
actfile_name = (char *)strcpy(actfile_name,name);
|
||||
#ifdef LINT
|
||||
name =
|
||||
#endif LINT
|
||||
strcat(actfile_name, ".c");
|
||||
fprintf(stdout, "debugging file is %s\n",actfile_name);
|
||||
break;
|
||||
case 'K':
|
||||
debug[c]=1;
|
||||
fprintf(OUT, "option %c file %s\n",c, &argv[i][j+1]);
|
||||
(void) strcpy(kerneldirname,&argv[i][++j]);
|
||||
break;
|
||||
case 'X':
|
||||
debug[c]=1;
|
||||
name = &argv[i][++j];
|
||||
astringfile_name = Malloc( strlen(name)+4);
|
||||
astringfile_name = (char *)strcpy(astringfile_name,name);
|
||||
#ifdef LINT
|
||||
name =
|
||||
#endif LINT
|
||||
strcat(astringfile_name, ".c");
|
||||
fprintf(OUT, "option %c, astringfile name %s\n",c, name);
|
||||
break;
|
||||
case 'E':
|
||||
name = &argv[i][++j];
|
||||
eventfile_h_name = Malloc( strlen(name)+4);
|
||||
eventfile_h_name = (char *)strcpy(eventfile_h_name,name);
|
||||
#ifdef LINT
|
||||
name =
|
||||
#endif LINT
|
||||
strcat(eventfile_h_name, ".h");
|
||||
fprintf(stdout, "event files is %s\n",eventfile_h_name);
|
||||
break;
|
||||
case 'I':
|
||||
name = &argv[i][++j];
|
||||
statevalfile_name = Malloc( strlen(name)+4 );
|
||||
statevalfile_name = (char *)strcpy(statevalfile_name,name);
|
||||
#ifdef LINT
|
||||
name =
|
||||
#endif LINT
|
||||
strcat(statevalfile_name, ".init");
|
||||
fprintf(stdout, "state table initial values file is %s\n",statevalfile_name);
|
||||
break;
|
||||
case 'S':
|
||||
name = &argv[i][++j];
|
||||
statefile_name = Malloc( strlen(name)+4);
|
||||
statefile_name = (char *)strcpy(statefile_name,name);
|
||||
#ifdef LINT
|
||||
name =
|
||||
#endif LINT
|
||||
strcat(statefile_name, ".h");
|
||||
fprintf(stdout, "state file is %s\n",statefile_name);
|
||||
break;
|
||||
/* END GROT */
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
debug['X']= (int)argv[i][j] - (int) '0';
|
||||
fprintf(OUT, "value of debug['X'] is 0x%x,%d\n", debug['X'],
|
||||
debug['X']);
|
||||
break;
|
||||
case 'D':
|
||||
while( c = argv[i][++j] ) {
|
||||
if(c == 'X') {
|
||||
fprintf(OUT, "debugging on");
|
||||
if(debug['X']) fprintf(OUT,
|
||||
" - overrides any -%d flags used\n", debug['X']);
|
||||
}
|
||||
debug[c]=1;
|
||||
fprintf(OUT, "debug %c\n",c);
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
pgoption = 1;
|
||||
fprintf(stdout, "Profiling\n");
|
||||
break;
|
||||
case 'e':
|
||||
print_protoerrs = 1;
|
||||
fprintf(stdout, "Protocol error table:\n");
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
print_trans = 1;
|
||||
fprintf(stdout, "Transitions:\n");
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(kerneldirname[0]) {
|
||||
char *c;
|
||||
#ifdef notdef
|
||||
if(debug['X']) {
|
||||
fprintf(OUT, "Option K overrides option X\n");
|
||||
debug['X'] = 0;
|
||||
}
|
||||
#endif notdef
|
||||
if(strlen(kerneldirname)<1) {
|
||||
fprintf(OUT, "K option: dir name too short!\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* add ../name/ */
|
||||
c = (char *) Malloc(strlen(kerneldirname)+6) ;
|
||||
if(c <= (char *)0) {
|
||||
fprintf(OUT, "Cannot allocate %d bytes for kerneldirname\n",
|
||||
strlen(kerneldirname + 6) );
|
||||
fprintf(OUT, "kerneldirname is %s\n", kerneldirname );
|
||||
exit(-1);
|
||||
}
|
||||
*c = '.';
|
||||
*(c+1) = '.';
|
||||
*(c+2) = '/';
|
||||
(void) strcat(c, kerneldirname);
|
||||
(void) strcat(c, "/\0");
|
||||
strcpy(kerneldirname, c);
|
||||
}
|
||||
|
||||
init_alloc();
|
||||
|
||||
(void) llparse();
|
||||
|
||||
/* {{ */
|
||||
if( !FirstEventAttribute )
|
||||
fprintf(eventfile_h, "\t}ev_union;\n");
|
||||
fprintf(eventfile_h, "};/* end struct event */\n");
|
||||
fprintf(eventfile_h, "\n#define %s_NEVENTS 0x%x\n", protocol, Nevents);
|
||||
fprintf(eventfile_h,
|
||||
"\n#define ATTR(X)ev_union.%s/**/X/**/\n",EV_PREFIX);
|
||||
(void) fclose(eventfile_h);
|
||||
|
||||
/* {{ */ fprintf(actfile, "\t}\nreturn 0;\n}\n"); /* end switch; end action() */
|
||||
dump_predtable(actfile);
|
||||
|
||||
putdriver(actfile, 3);
|
||||
IFDEBUG(X)
|
||||
if(!debug['K'])
|
||||
putdriver(actfile, 4);
|
||||
ENDDEBUG
|
||||
putdriver(actfile, 6);
|
||||
IFDEBUG(X)
|
||||
/*
|
||||
putdriver(actfile, 10);
|
||||
*/
|
||||
if(debug['K']) {
|
||||
putdriver(actfile, 11);
|
||||
} else {
|
||||
switch(debug['X']) {
|
||||
case 1:
|
||||
default:
|
||||
putdriver(actfile, 7);
|
||||
break;
|
||||
case 2:
|
||||
putdriver(actfile, 13);
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
}
|
||||
ENDDEBUG
|
||||
putdriver(actfile, 8);
|
||||
(void) fclose(actfile);
|
||||
IFDEBUG(X)
|
||||
/* { */
|
||||
fprintf(astringfile, "};\n");
|
||||
(void) fclose(astringfile);
|
||||
ENDDEBUG
|
||||
|
||||
(void) fclose(statevalfile);
|
||||
|
||||
fprintf(statefile, "\n#define %s_NSTATES 0x%x\n", protocol, Nstates);
|
||||
(void) fclose(statefile);
|
||||
|
||||
finish = time(0);
|
||||
fprintf(stdout, "%d seconds\n", finish - start);
|
||||
if( print_protoerrs )
|
||||
printprotoerrs();
|
||||
}
|
||||
|
||||
int transno = 0;
|
||||
|
||||
Exit(n)
|
||||
{
|
||||
fprintf(stderr, "Error at line %d\n",lineno);
|
||||
if(transno) fprintf(stderr, "Transition number %d\n",transno);
|
||||
(void) fflush(stdout);
|
||||
(void) fflush(statefile);
|
||||
(void) fflush(eventfile_h);
|
||||
(void) fflush(actfile);
|
||||
exit(n);
|
||||
}
|
||||
|
||||
syntax()
|
||||
{
|
||||
static char *synt[] = {
|
||||
"*PROTOCOL <string>\n",
|
||||
"*PCB <string> <optional: SYNONYM synonymstring>\n",
|
||||
"<optional: *INCLUDE {\n<C source>\n} >\n",
|
||||
"*STATES <string>\n",
|
||||
"*EVENTS <string>\n",
|
||||
"*TRANSITIONS <string>\n",
|
||||
};
|
||||
}
|
||||
|
||||
FakeFilename(outfile, name, l)
|
||||
FILE *outfile;
|
||||
char *name;
|
||||
int l;
|
||||
{
|
||||
/*
|
||||
doesn't work
|
||||
fprintf(outfile, "\n\n\n\n# line %d \"%s\"\n", l, name);
|
||||
*/
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/main.h,v 1.1.1.1 1994/05/24 10:07:49 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/main.h,v $ */
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define LINELEN 2350
|
||||
/* approx limit on token size for C compiler
|
||||
* which matters for the purpose of debugging (astring.c...)
|
||||
*/
|
||||
|
||||
#define MSIZE 4000
|
||||
#define DEBUGFILE "astring.c"
|
||||
#define ACTFILE "driver.c"
|
||||
#define EVENTFILE_H "events.h"
|
||||
#define STATEFILE "states.h"
|
||||
#define STATEVALFILE "states.init"
|
||||
|
||||
#define EV_PREFIX "EV_"
|
||||
#define ST_PREFIX "ST_"
|
||||
|
||||
#define PCBNAME "_PCB_"
|
||||
|
||||
extern char kerneldirname[];
|
||||
extern char protocol[];
|
||||
extern char *synonyms[];
|
||||
#define EVENT_SYN 0
|
||||
#define PCB_SYN 1
|
||||
|
||||
extern int transno;
|
||||
extern int print_trans;
|
||||
extern char *stash();
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/malloc.c,v 1.1.1.1 1994/05/24 10:07:48 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/malloc.c,v $ */
|
||||
/*
|
||||
* This code is such a kludge that I don't want to put my name on it.
|
||||
* It was a ridiculously fast hack and needs rewriting.
|
||||
* However it does work...
|
||||
*/
|
||||
|
||||
/*
|
||||
* a simple malloc
|
||||
* it might be brain-damaged but for the purposes of xebec
|
||||
* it's a whole lot faster than the c library malloc
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "malloc.h"
|
||||
#include "debug.h"
|
||||
#define CHUNKSIZE 4096*2
|
||||
|
||||
static char *hiwat, *highend;
|
||||
int bytesmalloced=0;
|
||||
int byteswasted = 0;
|
||||
|
||||
|
||||
init_alloc()
|
||||
{
|
||||
#ifdef LINT
|
||||
hiwat = 0;
|
||||
highend = 0;
|
||||
#else LINT
|
||||
extern char *sbrk();
|
||||
|
||||
hiwat = (char *) sbrk(0);
|
||||
hiwat = (char *)((unsigned)(hiwat + 3) & ~0x3);
|
||||
highend = hiwat;
|
||||
#endif LINT
|
||||
}
|
||||
|
||||
HIWAT(s)
|
||||
char *s;
|
||||
{
|
||||
IFDEBUG(M)
|
||||
fprintf(stdout, "HIWAT 0x%x %s\n", hiwat,s);
|
||||
fflush(stdout);
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
#define MIN(x,y) ((x<y)?x:y)
|
||||
|
||||
char *Malloc(x)
|
||||
int x;
|
||||
{
|
||||
char *c;
|
||||
extern char *sbrk();
|
||||
static int firsttime=1;
|
||||
int total = x;
|
||||
int first_iter = 1;
|
||||
char *returnvalue;
|
||||
|
||||
IFDEBUG(N)
|
||||
fprintf(stdout, "Malloc 0x%x, %d, bytesmalloced %d\n",
|
||||
total,total, bytesmalloced);
|
||||
fflush(stdout);
|
||||
ENDDEBUG
|
||||
IFDEBUG(M)
|
||||
fprintf(stdout, "Malloc 0x%x, %d, hiwat 0x%x\n",
|
||||
total,total, hiwat);
|
||||
fflush(stdout);
|
||||
ENDDEBUG
|
||||
if(firsttime) {
|
||||
hiwat = sbrk(0);
|
||||
if(((unsigned)(hiwat) & 0x3)) {
|
||||
bytesmalloced = 4 - (int) ((unsigned)(hiwat) & 0x3);
|
||||
hiwat = sbrk( bytesmalloced );
|
||||
} else
|
||||
bytesmalloced = 0;
|
||||
firsttime = 0;
|
||||
highend = hiwat;
|
||||
}
|
||||
while( total ) {
|
||||
x = MIN(CHUNKSIZE, total);
|
||||
if(total != x) {
|
||||
IFDEBUG(N)
|
||||
fprintf(stdout, "BIG Malloc tot %d, x %d, left %d net %d\n",
|
||||
total,x, total-x, bytesmalloced);
|
||||
fflush(stdout);
|
||||
ENDDEBUG
|
||||
}
|
||||
if ( (hiwat + x) > highend) {
|
||||
c = sbrk(CHUNKSIZE);
|
||||
IFDEBUG(M)
|
||||
fprintf(stdout, "hiwat 0x%x, x 0x%x, highend 0x%x, c 0x%x\n",
|
||||
hiwat, x, highend, c);
|
||||
fflush(stdout);
|
||||
ENDDEBUG
|
||||
if( c == (char *) -1 ) {
|
||||
fprintf(stderr, "Ran out of memory!\n");
|
||||
Exit(-1);
|
||||
}
|
||||
if(first_iter) {
|
||||
returnvalue = c;
|
||||
first_iter = 0;
|
||||
}
|
||||
bytesmalloced += CHUNKSIZE;
|
||||
IFDEBUG(m)
|
||||
if (highend != c) {
|
||||
fprintf(OUT, "warning: %d wasted bytes!\n", highend - hiwat);
|
||||
fprintf(OUT, " chunksize 0x%x, x 0x%x \n", CHUNKSIZE, x);
|
||||
}
|
||||
ENDDEBUG
|
||||
highend = c + CHUNKSIZE;
|
||||
hiwat = c;
|
||||
}
|
||||
c = hiwat;
|
||||
if(first_iter) {
|
||||
returnvalue = c;
|
||||
first_iter = 0;
|
||||
}
|
||||
hiwat += x;
|
||||
total -= x;
|
||||
}
|
||||
if((unsigned)hiwat & 0x3) {
|
||||
byteswasted += (int)((unsigned)(hiwat) & 0x3);
|
||||
hiwat = (char *)((unsigned)(hiwat + 3) & ~0x3);
|
||||
}
|
||||
IFDEBUG(M)
|
||||
fprintf(stdout, "Malloc = 0x%x, bytesm 0x%x, wasted 0x%x, hiwat 0x%x\n",
|
||||
returnvalue, bytesmalloced, byteswasted, hiwat);
|
||||
ENDDEBUG
|
||||
IFDEBUG(N)
|
||||
fprintf(stdout, "Malloc returns 0x%x, sbrk(0) 0x%x\n", returnvalue, sbrk(0));
|
||||
fflush(stdout);
|
||||
ENDDEBUG
|
||||
return(returnvalue);
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
/* $Header: malloc.h,v 2.1 88/09/19 12:56:27 nhall Exp $ */
|
||||
/* $Source: /var/home/tadl/src/argo/xebec/RCS/malloc.h,v $ */
|
||||
|
||||
char *Malloc();
|
||||
@@ -1,437 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/procs.c,v 1.1.1.1 1994/05/24 10:07:46 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/procs.c,v $ */
|
||||
/*
|
||||
* This code is such a kludge that I don't want to put my name on it.
|
||||
* It was a ridiculously fast hack and needs rewriting.
|
||||
* However it does work...
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include "malloc.h"
|
||||
#include "main.h"
|
||||
#include "debug.h"
|
||||
#include "sets.h"
|
||||
#include "procs.h"
|
||||
|
||||
struct Predicate {
|
||||
int p_index;
|
||||
int p_transno;
|
||||
char *p_str;
|
||||
struct Predicate *p_next;
|
||||
};
|
||||
|
||||
struct Stateent {
|
||||
int s_index;
|
||||
int s_newstate;
|
||||
int s_action;
|
||||
struct Stateent *s_next;
|
||||
};
|
||||
|
||||
struct Object *SameState = (struct Object *)-1;
|
||||
int Index = 0;
|
||||
int Nstates = 0;
|
||||
int Nevents = 0;
|
||||
struct Predicate **Predlist;
|
||||
struct Stateent **Statelist;
|
||||
extern FILE *astringfile;
|
||||
|
||||
end_events() {
|
||||
int size, part;
|
||||
char *addr;
|
||||
|
||||
IFDEBUG(X)
|
||||
/* finish estring[], start astring[] */
|
||||
if(debug['X'] < 2 )
|
||||
fprintf(astringfile, "};\n\nchar *%s_astring[] = {\n\"NULLACTION\",\n",
|
||||
protocol);
|
||||
ENDDEBUG
|
||||
/* NOSTRICT */
|
||||
Statelist =
|
||||
(struct Stateent **) Malloc((Nstates+1) * sizeof(struct Statent *));
|
||||
/* NOSTRICT */
|
||||
Predlist =
|
||||
(struct Predicate **)
|
||||
Malloc ( (((Nevents)<<Eventshift)+Nstates)*sizeof(struct Predicate *) );
|
||||
|
||||
size = (((Nevents)<<Eventshift)+Nstates)*sizeof(struct Predicate *) ;
|
||||
addr = (char *)Predlist;
|
||||
IFDEBUG(N)
|
||||
fprintf(OUT, "Predlist at 0x%x, sbrk 0x%x bzero size %d at addr 0x%x\n",
|
||||
Predlist, sbrk(0), size, addr);
|
||||
ENDDEBUG
|
||||
#define BZSIZE 8192
|
||||
while(size) {
|
||||
part = size>BZSIZE?BZSIZE:size;
|
||||
IFDEBUG(N)
|
||||
fprintf(OUT, "bzero addr 0x%x part %d size %d\n",addr, part, size);
|
||||
ENDDEBUG
|
||||
bzero(addr, part);
|
||||
IFDEBUG(N)
|
||||
fprintf(OUT, "after bzero addr 0x%x part %d size %d\n",addr, part, size);
|
||||
ENDDEBUG
|
||||
addr += part;
|
||||
size -= part;
|
||||
|
||||
}
|
||||
IFDEBUG(N)
|
||||
fprintf(OUT, "endevents..done \n");
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
int acttable(f,actstring)
|
||||
char *actstring;
|
||||
FILE *f;
|
||||
{
|
||||
static Actindex = 0;
|
||||
extern FILE *astringfile;
|
||||
extern int pgoption;
|
||||
|
||||
IFDEBUG(a)
|
||||
fprintf(OUT,"acttable()\n");
|
||||
ENDDEBUG
|
||||
fprintf(f, "case 0x%x: \n", ++Actindex);
|
||||
|
||||
if(pgoption) {
|
||||
fprintf(f, "asm(\" # dummy statement\");\n");
|
||||
fprintf(f, "asm(\"_Xebec_action_%x: \");\n", Actindex );
|
||||
fprintf(f, "asm(\".data\");\n");
|
||||
fprintf(f, "asm(\".globl _Xebec_action_%x# X profiling\");\n",
|
||||
Actindex );
|
||||
fprintf(f, "asm(\".long 0 # X profiling\");\n");
|
||||
fprintf(f, "asm(\".text # X profiling\");\n");
|
||||
fprintf(f, "asm(\"cas r0,r15,r0 # X profiling\");\n");
|
||||
fprintf(f, "asm(\"bali r15,mcount # X profiling\");\n");
|
||||
}
|
||||
|
||||
fprintf(f, "\t\t%s\n\t\t break;\n", actstring);
|
||||
IFDEBUG(X)
|
||||
if(debug['X']<2) {
|
||||
register int len = 0;
|
||||
fputc('"',astringfile);
|
||||
while(*actstring) {
|
||||
if( *actstring == '\n' ) {
|
||||
fputc('\\', astringfile);
|
||||
len++;
|
||||
fputc('n', astringfile);
|
||||
} else if (*actstring == '\\') {
|
||||
fputc('\\', astringfile);
|
||||
len ++;
|
||||
fputc('\\', astringfile);
|
||||
} else if (*actstring == '\"') {
|
||||
fputc('\\', astringfile);
|
||||
len ++;
|
||||
fputc('\"', astringfile);
|
||||
} else fputc(*actstring, astringfile);
|
||||
actstring++;
|
||||
len++;
|
||||
}
|
||||
fprintf(astringfile,"\",\n");
|
||||
if (len > LINELEN) {
|
||||
fprintf(stderr, "Action too long: %d\n",len); Exit(-1);
|
||||
}
|
||||
}
|
||||
ENDDEBUG
|
||||
|
||||
return(Actindex);
|
||||
}
|
||||
|
||||
static int Npred=0, Ndefpred=0, Ntrans=0, Ndefevent=0, Nnulla=0;
|
||||
|
||||
statetable(string, oldstate, newstate, action, event)
|
||||
char *string;
|
||||
int action;
|
||||
struct Object *oldstate, *newstate, *event;
|
||||
{
|
||||
register int different;
|
||||
|
||||
IFDEBUG(a)
|
||||
fprintf(OUT,"statetable(0x%x, 0x%x,0x%x, 0x%x)\n",
|
||||
string, oldstate, newstate, action);
|
||||
fprintf(OUT,"statetable(%s, %s,%s, 0x%x)\n",
|
||||
string, oldstate->obj_name, newstate->obj_name, action);
|
||||
ENDDEBUG
|
||||
|
||||
if( !action) Nnulla++;
|
||||
if( newstate->obj_kind == OBJ_SET) {
|
||||
fprintf(stderr, "Newstate cannot be a set\n");
|
||||
Exit(-1);
|
||||
}
|
||||
different = (newstate != SameState);
|
||||
|
||||
(void) predtable( oldstate, event, string,
|
||||
action, (newstate->obj_number) * different );
|
||||
IFDEBUG(a)
|
||||
fprintf(OUT,"EXIT statetable\n");
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
stateentry(index, oldstate, newstate, action)
|
||||
int index, action;
|
||||
int oldstate, newstate;
|
||||
{
|
||||
extern FILE *statevalfile;
|
||||
|
||||
IFDEBUG(a)
|
||||
fprintf(OUT,"stateentry(0x%x,0x%x,0x%x,0x%x) Statelist@0x%x, val 0x%x\n",
|
||||
index, oldstate, newstate,action, &Statelist, Statelist);
|
||||
ENDDEBUG
|
||||
|
||||
|
||||
fprintf(statevalfile, "{0x%x,0x%x},\n", newstate, action);
|
||||
}
|
||||
|
||||
int predtable(os, oe, str, action, newstate)
|
||||
struct Object *os, *oe;
|
||||
char *str;
|
||||
int action, newstate;
|
||||
{
|
||||
register struct Predicate *p, **q;
|
||||
register int event, state;
|
||||
register struct Object *e, *s;
|
||||
struct Object *firste;
|
||||
|
||||
if (oe == (struct Object *)0 ) {
|
||||
Ndefevent ++;
|
||||
fprintf(stderr, "DEFAULT EVENTS aren't implemented; trans ignored\n");
|
||||
return;
|
||||
}
|
||||
Ntrans++;
|
||||
IFDEBUG(g)
|
||||
fprintf(stdout,
|
||||
"PREDTAB: s %5s; e %5s\n", os->obj_kind==OBJ_SET?"SET":"item",
|
||||
oe->obj_kind==OBJ_SET?"SET":"item");
|
||||
ENDDEBUG
|
||||
if (os->obj_kind == OBJ_SET) s = os->obj_members;
|
||||
else s = os;
|
||||
if (oe->obj_kind == OBJ_SET) firste = oe->obj_members;
|
||||
else firste = oe;
|
||||
if(newstate) {
|
||||
fprintf(statevalfile, "{0x%x,0x%x},\n",newstate, action);
|
||||
Index++;
|
||||
}
|
||||
while (s) {
|
||||
if( !newstate ) { /* !newstate --> SAME */
|
||||
/* i.e., use old obj_number */
|
||||
fprintf(statevalfile, "{0x%x,0x%x},\n",s->obj_number, action);
|
||||
Index++;
|
||||
}
|
||||
e = firste;
|
||||
while (e) {
|
||||
event = e->obj_number; state = s->obj_number;
|
||||
IFDEBUG(g)
|
||||
fprintf(stdout,"pred table event=0x%x, state 0x%x\n",
|
||||
event, state);
|
||||
fflush(stdout);
|
||||
ENDDEBUG
|
||||
if( !str /* DEFAULT PREDICATE */) {
|
||||
Ndefpred++;
|
||||
IFDEBUG(g)
|
||||
fprintf(stdout,
|
||||
"DEFAULT pred state 0x%x, event 0x%x, Index 0x%x\n",
|
||||
state, event, Index);
|
||||
fflush(stdout);
|
||||
ENDDEBUG
|
||||
} else
|
||||
Npred++;
|
||||
/* put at END of list */
|
||||
#ifndef LINT
|
||||
IFDEBUG(g)
|
||||
fprintf(stdout,
|
||||
"predicate for event 0x%x, state 0x%x is 0x%x, %s\n",
|
||||
event, state, Index, str);
|
||||
fflush(stdout);
|
||||
ENDDEBUG
|
||||
#endif LINT
|
||||
for( ((q = &Predlist[(event<<Eventshift)+state]),
|
||||
(p = Predlist[(event<<Eventshift)+state]));
|
||||
p ; p = p->p_next ) {
|
||||
q = &p->p_next;
|
||||
}
|
||||
|
||||
p = (struct Predicate *)Malloc(sizeof(struct Predicate));
|
||||
p->p_next = (struct Predicate *)0;
|
||||
p->p_str = str;
|
||||
p->p_index = Index;
|
||||
p->p_transno = transno;
|
||||
*q = p;
|
||||
|
||||
IFDEBUG(g)
|
||||
fprintf(stdout,
|
||||
"predtable index 0x%x, transno %d, E 0x%x, S 0x%x\n",
|
||||
Index, transno, e, s);
|
||||
ENDDEBUG
|
||||
|
||||
e = e->obj_members;
|
||||
}
|
||||
s = s->obj_members;
|
||||
}
|
||||
return Index ;
|
||||
}
|
||||
|
||||
printprotoerrs()
|
||||
{
|
||||
register int e,s;
|
||||
|
||||
fprintf(stderr, "[ Event, State ] without any transitions :\n");
|
||||
for(e = 0; e < Nevents; e++) {
|
||||
fprintf(stderr, "Event 0x%x: states ", e);
|
||||
for(s = 0; s < Nstates; s++) {
|
||||
if( Predlist[(e<<Eventshift)+s] == 0 )
|
||||
fprintf(stderr, "0x%x ", s);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LINT
|
||||
dump_predtable(f)
|
||||
FILE *f;
|
||||
{
|
||||
struct Predicate *p;
|
||||
register int e,s, hadapred;
|
||||
int defaultindex;
|
||||
int defaultItrans;
|
||||
extern int bytesmalloced;
|
||||
extern int byteswasted;
|
||||
|
||||
#ifdef notdef
|
||||
fprintf(stdout,
|
||||
" Xebec used %8d bytes of storage, wasted %8d bytes\n",
|
||||
bytesmalloced, byteswasted);
|
||||
#endif notdef
|
||||
fprintf(stdout,
|
||||
" %8d states\n %8d events\n %8d transitions\n",
|
||||
Nstates, Nevents, Ntrans);
|
||||
fprintf(stdout,
|
||||
" %8d predicates\n %8d default predicates used\n",
|
||||
Npred, Ndefpred);
|
||||
fprintf(stdout,
|
||||
" %8d null actions\n",
|
||||
Nnulla);
|
||||
|
||||
putdriver(f, 5);
|
||||
for(e = 0; e < Nevents; e++) { for(s = 0; s < Nstates; s++) {
|
||||
p = Predlist[(e<<Eventshift)+s];
|
||||
hadapred=0;
|
||||
defaultindex=0;
|
||||
defaultItrans=0;
|
||||
if(p) {
|
||||
IFDEBUG(d)
|
||||
fflush(f);
|
||||
ENDDEBUG
|
||||
while(p) {
|
||||
if(p->p_str) {
|
||||
if(!hadapred)
|
||||
fprintf(f, "case 0x%x:\n\t", (e<<Eventshift) + s);
|
||||
hadapred = 1;
|
||||
fprintf(f, "if %s return 0x%x;\n\t else ",
|
||||
p->p_str, p->p_index);
|
||||
} else {
|
||||
if(defaultindex) {
|
||||
fprintf(stderr,
|
||||
"\nConflict between transitions %d and %d: duplicate default \n",
|
||||
p->p_transno, defaultItrans);
|
||||
Exit(-1);
|
||||
}
|
||||
defaultindex = p->p_index;
|
||||
defaultItrans = p->p_transno;
|
||||
}
|
||||
p = p->p_next;
|
||||
}
|
||||
if( hadapred) {
|
||||
fprintf(f, "return 0x%x;\n", defaultindex);
|
||||
}
|
||||
IFDEBUG(d)
|
||||
fflush(f);
|
||||
ENDDEBUG
|
||||
}
|
||||
IFDEBUG(g)
|
||||
fprintf(stdout,
|
||||
"loop: e 0x%x s 0x%x hadapred 0x%x dindex 0x%x for trans 0x%x\n",
|
||||
e, s, hadapred, defaultindex, defaultItrans);
|
||||
ENDDEBUG
|
||||
if ( hadapred ) {
|
||||
/* put a -1 in the array - Predlist is temporary storage */
|
||||
Predlist[(e<<Eventshift)+s] = (struct Predicate *)(-1);
|
||||
} else {
|
||||
/* put defaultindex in the array */
|
||||
/* if defaultindex is zero, then the driver will
|
||||
* cause an erroraction (same as if no default
|
||||
* were given and none of the predicates were true;
|
||||
* also same as if no preds or defaults were given
|
||||
* for this combo)
|
||||
*/
|
||||
Predlist[(e<<Eventshift)+s] = (struct Predicate *)(defaultindex);
|
||||
}
|
||||
} }
|
||||
fprintf(f, "default: return 0;\n} /* end switch */\n");
|
||||
#ifdef notdef
|
||||
fprintf(f, "/*NOTREACHED*/return 0;\n} /* _Xebec_index() */\n");
|
||||
#else notdef
|
||||
fprintf(f, "} /* _Xebec_index() */\n");
|
||||
#endif notdef
|
||||
fprintf(f, "static int inx[%d][%d] = { {", Nevents+1,Nstates);
|
||||
for(s = 0; s< Nstates; s++) fprintf(f, "0,"); /* event 0 */
|
||||
fprintf(f, "},\n");
|
||||
|
||||
for(e = 0; e < Nevents; e++) {
|
||||
fprintf(f, " {");
|
||||
for(s = 0; s < Nstates; s++) {
|
||||
register struct Predicate *xyz = Predlist[(e<<Eventshift)+s];
|
||||
/* this kludge is to avoid a lint msg. concerning
|
||||
* loss of bits
|
||||
*/
|
||||
if (xyz == (struct Predicate *)(-1))
|
||||
fprintf(f, "-1,");
|
||||
else
|
||||
fprintf(f, "0x%x,", Predlist[(e<<Eventshift)+s]);
|
||||
}
|
||||
fprintf(f, " },\n");
|
||||
}
|
||||
fprintf(f, "};");
|
||||
}
|
||||
#endif LINT
|
||||
|
||||
char *
|
||||
stash(buf)
|
||||
char *buf;
|
||||
{
|
||||
register int len;
|
||||
register char *c;
|
||||
|
||||
/* grot */
|
||||
len = strlen(buf);
|
||||
c = Malloc(len+1);
|
||||
#ifdef LINT
|
||||
c =
|
||||
#endif LINT
|
||||
strcpy(c, buf);
|
||||
|
||||
IFDEBUG(z)
|
||||
fprintf(stdout,"stash %s at 0x%x\n", c,c);
|
||||
ENDDEBUG
|
||||
return(c);
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
dump_pentry(event,state)
|
||||
int event,state;
|
||||
{
|
||||
register struct Predicate *p, **q;
|
||||
|
||||
for(
|
||||
((q = &Predlist[(event<<Eventshift) +state]),
|
||||
(p = Predlist[(event<<Eventshift) + state]));
|
||||
p!= (struct Predicate *)0 ; p = p->p_next ) {
|
||||
#ifndef LINT
|
||||
IFDEBUG(a)
|
||||
fprintf(OUT,
|
||||
"dump_pentry for event 0x%x, state 0x%x is 0x%x\n",
|
||||
event, state, p);
|
||||
ENDDEBUG
|
||||
#endif LINT
|
||||
q = &p->p_next;
|
||||
}
|
||||
}
|
||||
#endif notdef
|
||||
@@ -1,5 +0,0 @@
|
||||
/* $Header: procs.h,v 2.1 88/09/19 12:56:30 nhall Exp $ */
|
||||
/* $Source: /var/home/tadl/src/argo/xebec/RCS/procs.h,v $ */
|
||||
|
||||
extern char *stash();
|
||||
extern struct Object *SameState;
|
||||
@@ -1,244 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/putdriver.c,v 1.1.1.1 1994/05/24 10:07:46 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/putdriver.c,v $ */
|
||||
|
||||
/*
|
||||
* This code is such a kludge that I don't want to put my name on it.
|
||||
* It was a ridiculously fast hack and needs rewriting.
|
||||
* However it does work...
|
||||
*/
|
||||
|
||||
/* The original idea was to put all the driver code
|
||||
* in one place so it would be easy to modify
|
||||
* but as hacks got thrown in it got worse and worse...
|
||||
* It's to the point where a user would be better off
|
||||
* writing his own driver and xebec should JUST produce
|
||||
* the tables.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "main.h"
|
||||
#include "debug.h"
|
||||
|
||||
extern char protocol[];
|
||||
char Eventshiftstring[10];
|
||||
static char statename[] = {'_', 's', 't', 'a', 't', 'e', 0 };
|
||||
|
||||
static char *strings[] = {
|
||||
|
||||
#define PART1 { 0,3 }
|
||||
|
||||
"\n#include \"",
|
||||
kerneldirname,
|
||||
protocol,
|
||||
"_states.h\"",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART12 { 10,12 }
|
||||
"\n\nstatic struct act_ent {\n",
|
||||
"\tint a_newstate;\n\tint a_action;\n",
|
||||
"} statetable[] = { {0,0},\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART2 { 20,20 }
|
||||
"};\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART3 { 30,41 }
|
||||
"\n",
|
||||
protocol,
|
||||
"_driver(p, e)\nregister ",
|
||||
protocol,
|
||||
PCBNAME,
|
||||
" *p;\nregister struct ",
|
||||
protocol,
|
||||
"_event *e;\n",
|
||||
"{\n",
|
||||
"\tregister int index, error=0;\n",
|
||||
"\tstruct act_ent *a;\n",
|
||||
"\tstatic struct act_ent erroraction = {0,-1};\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART4 { 50,54 }
|
||||
|
||||
"\textern int ",
|
||||
protocol,
|
||||
"_debug;\n\textern FILE *",
|
||||
protocol,
|
||||
"_astringfile;\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART6 { 60, 65 }
|
||||
"\n\tindex = inx[1 + e->ev_number][p->",
|
||||
protocol,
|
||||
statename,
|
||||
"];\n\tif(index<0) index=_Xebec_index(e, p);\n",
|
||||
"\tif (index==0) {\n\t\ta = &erroraction;\n",
|
||||
"\t} else\n\t\ta = &statetable[index];\n\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART7 {70, 77 }
|
||||
"\tif(",
|
||||
protocol,
|
||||
"_debug) fprintf(",
|
||||
protocol,
|
||||
"_astringfile, \"%15s <-- %15s [%15s] \\n\\t%s\\n\",\n",
|
||||
"\t\tsstring[a->a_newstate], sstring[p->",
|
||||
protocol,
|
||||
"_state], estring[e->ev_number], astring[a->a_action]);\n\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART8 { 80, 84 }
|
||||
"\tif(a->a_action)\n",
|
||||
"\t\terror = _Xebec_action( a->a_action, e, p );\n",
|
||||
"\tif(error==0)\n\tp->",
|
||||
protocol,
|
||||
"_state = a->a_newstate;\n\treturn error;\n}\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART9 { 90, 99 }
|
||||
"\n_XEBEC_PG int _Xebec_action(a,e,p)\nint a;\nstruct ",
|
||||
protocol,
|
||||
"_event *e;\n",
|
||||
protocol,
|
||||
PCBNAME,
|
||||
" *p;\n{\n",
|
||||
"switch(a) {\n",
|
||||
"case -1: return ",
|
||||
protocol,
|
||||
"_protocol_error(e,p);\n",
|
||||
(char *)0,
|
||||
|
||||
#define PART10 { 101, 105 }
|
||||
"\tif(",
|
||||
protocol,
|
||||
"_debug) fprintf(",
|
||||
protocol,
|
||||
"_astringfile, \"index 0x%5x\\n\", index);\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART5 { 110, 121 }
|
||||
"\n_XEBEC_PG int\n_Xebec_index( e,p )\n",
|
||||
"\tstruct ",
|
||||
protocol,
|
||||
"_event *e;\n\t",
|
||||
protocol,
|
||||
PCBNAME,
|
||||
" *p;\n{\nswitch( (e->ev_number<<",
|
||||
Eventshiftstring,
|
||||
")+(p->",
|
||||
protocol,
|
||||
statename,
|
||||
") ) {\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART11 {130, 137 }
|
||||
"\tIFTRACE(D_DRIVER)\n",
|
||||
"\t",
|
||||
protocol,
|
||||
"trace(DRIVERTRACE,",
|
||||
"\t\ta->a_newstate, p->",
|
||||
protocol,
|
||||
"_state, e->ev_number, a->a_action, 0);\n\n",
|
||||
"\tENDTRACE\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART13 {140, 147 }
|
||||
"\tif(",
|
||||
protocol,
|
||||
"_debug) fprintf(",
|
||||
protocol,
|
||||
"_astringfile, \"%15s <-- %15s [%15s] \\n\",\n",
|
||||
"\t\tsstring[a->a_newstate], sstring[p->",
|
||||
protocol,
|
||||
"_state], estring[e->ev_number]);\n\n",
|
||||
(char *)0,
|
||||
(char *)0,
|
||||
|
||||
#define PART14 { 150,150 }
|
||||
"#define _XEBEC_PG static\n",
|
||||
|
||||
#define PART15 { 151,151 }
|
||||
"#define _XEBEC_PG \n",
|
||||
|
||||
};
|
||||
|
||||
static struct { int start; int finish; } parts[] = {
|
||||
{ 0,0 },
|
||||
PART1,
|
||||
PART2,
|
||||
PART3,
|
||||
PART4,
|
||||
PART5,
|
||||
PART6,
|
||||
PART7,
|
||||
PART8,
|
||||
PART9,
|
||||
PART10,
|
||||
PART11,
|
||||
PART12,
|
||||
PART13,
|
||||
PART14,
|
||||
PART15,
|
||||
};
|
||||
|
||||
putdriver(f, x)
|
||||
FILE *f;
|
||||
int x;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for( i = parts[x].start; i<= parts[x].finish; i++)
|
||||
fprintf(f, "%s", strings[i]);
|
||||
IFDEBUG(d)
|
||||
fflush(f);
|
||||
ENDDEBUG
|
||||
}
|
||||
@@ -1,472 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/sets.c,v 1.1.1.1 1994/05/24 10:07:45 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/sets.c,v $ */
|
||||
/*
|
||||
* This code is such a kludge that I don't want to put my name on it.
|
||||
* It was a ridiculously fast hack and needs rewriting.
|
||||
* However it does work...
|
||||
*/
|
||||
#include "main.h"
|
||||
#include "malloc.h"
|
||||
#include "sets.h"
|
||||
#include "debug.h"
|
||||
#include <stdio.h>
|
||||
|
||||
struct Object *CurrentEvent = (struct Object *)0;
|
||||
struct Object *Objtree;
|
||||
struct Object dummy;
|
||||
/*
|
||||
* define a set w/ type and name
|
||||
* return a set number
|
||||
*/
|
||||
#undef NULL
|
||||
#define NULL (struct Object *)0
|
||||
|
||||
static FILE *Sfile, *Efile;
|
||||
extern FILE *astringfile;
|
||||
char *Noname = "Unnamed set\0";
|
||||
|
||||
initsets(f,s)
|
||||
FILE *f, *s;
|
||||
{
|
||||
static char errorstring[20];
|
||||
extern struct Object *SameState;
|
||||
Efile = f;
|
||||
Sfile = s;
|
||||
|
||||
IFDEBUG(X)
|
||||
fprintf(astringfile, "char *%s_sstring[] = {\n", protocol);
|
||||
ENDDEBUG
|
||||
sprintf(errorstring, "%sERROR\0", ST_PREFIX);
|
||||
defineitem(STATESET, errorstring, (char *)0); /* state 0 */
|
||||
SameState = (struct Object *) Malloc( sizeof (struct Object) );
|
||||
SameState->obj_kind = OBJ_ITEM;
|
||||
SameState->obj_type = STATESET;
|
||||
SameState->obj_name = "SAME";
|
||||
SameState->obj_struc = (char *)0;
|
||||
SameState->obj_number = 0;
|
||||
SameState->obj_members = (struct Object *)0;
|
||||
SameState->obj_left = (struct Object *)0;
|
||||
SameState->obj_right = (struct Object *)0;
|
||||
SameState->obj_parent = (struct Object *)0;
|
||||
}
|
||||
|
||||
/*
|
||||
* get a set based on its type and name
|
||||
* returns address of an Object, may be set or item
|
||||
*/
|
||||
|
||||
struct Object *lookup(type, name)
|
||||
unsigned char type;
|
||||
char *name;
|
||||
{
|
||||
register struct Object *p = Objtree;
|
||||
int val = 1 ;
|
||||
|
||||
IFDEBUG(o)
|
||||
fprintf(stdout,"lookup 0x%x,%s \n",
|
||||
type, name);
|
||||
ENDDEBUG
|
||||
|
||||
while( p && val ) {
|
||||
IFDEBUG(o)
|
||||
fprintf(OUT, "lookup strcmp 0x%x,%s, 0x%x,%s\n",
|
||||
name, name, OBJ_NAME(p), OBJ_NAME(p));
|
||||
ENDDEBUG
|
||||
if( p->obj_name == (char *)0 ) {
|
||||
fprintf(stderr, "Unnamed set in table!\n");
|
||||
Exit(-1);
|
||||
}
|
||||
val = (int) strcmp(name, OBJ_NAME(p));
|
||||
if(val < 0) {
|
||||
/* left */
|
||||
p = p->obj_left;
|
||||
} else if (val > 0) {
|
||||
/* right */
|
||||
p = p->obj_right;
|
||||
}
|
||||
}
|
||||
if( p && ( p->obj_type != type)) {
|
||||
fprintf(stdout, "lookup(0x%x,%s) found wrong obj type 0x%x\n",
|
||||
type,name, p->obj_type);
|
||||
p = NULL;
|
||||
}
|
||||
IFDEBUG(o)
|
||||
fprintf(stdout,"lookup 0x%x,%s returning 0x%x\n",type, name, p);
|
||||
ENDDEBUG
|
||||
return(p);
|
||||
}
|
||||
|
||||
static int states_done = 0;
|
||||
|
||||
end_states(f)
|
||||
FILE *f;
|
||||
{
|
||||
register unsigned n = Nstates;
|
||||
register int i;
|
||||
extern char Eventshiftstring[];
|
||||
|
||||
states_done = 1;
|
||||
|
||||
for( i = 0; ;i++) {
|
||||
if( (n >>= 1) <= 0 ) break;
|
||||
}
|
||||
Eventshift = i+1;
|
||||
IFDEBUG(d)
|
||||
fprintf(OUT, "Eventshift=%d\n", Eventshift);
|
||||
ENDDEBUG
|
||||
sprintf(Eventshiftstring, "%d\0",Eventshift);
|
||||
fprintf(f, "struct %s_event {\n\tint ev_number;\n", &protocol[0]);
|
||||
IFDEBUG(X)
|
||||
/* finish sstring[] & start estring[] */
|
||||
fprintf(astringfile,
|
||||
"};\n\nchar *%s_estring[] = {\n", protocol);
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
int FirstEventAttribute = 1;
|
||||
|
||||
static
|
||||
insert(o)
|
||||
struct Object *o;
|
||||
{
|
||||
struct Object *p = Objtree;
|
||||
struct Object **q = &Objtree;
|
||||
int val=1;
|
||||
|
||||
|
||||
if (o->obj_name == (char *)0) {
|
||||
fprintf(stderr, "Internal Error: inserting unnamed object\n");
|
||||
Exit(-1);
|
||||
}
|
||||
if( o->obj_type == STATESET) {
|
||||
if( states_done ) {
|
||||
fprintf(stderr, "No states may be defined after *TRANSITIONS\n");
|
||||
Exit(-1);
|
||||
}
|
||||
o->obj_number = Nstates++ ;
|
||||
if(Nstates > MAXSTATES) {
|
||||
fprintf(stderr, "Too many states\n");
|
||||
Exit(-1);
|
||||
}
|
||||
fprintf(Sfile, "#define %s 0x%x\n", o->obj_name, o->obj_number);
|
||||
IFDEBUG(X)
|
||||
fprintf(astringfile, "\"%s(0x%x)\",\n", o->obj_name, o->obj_number);
|
||||
ENDDEBUG
|
||||
} else {
|
||||
/* EVENTSET */
|
||||
if( ! states_done ) {
|
||||
fprintf(stderr, "states must precede events\n");
|
||||
Exit(-1);
|
||||
}
|
||||
o->obj_number = Nevents++ ;
|
||||
if(Nevents > MAXEVENTS) {
|
||||
fprintf(stderr, "Too many events\n");
|
||||
Exit(-1);
|
||||
}
|
||||
if(o->obj_struc) {
|
||||
if( FirstEventAttribute ) {
|
||||
fprintf(Efile, "\n\tunion{\n"); /*} */
|
||||
FirstEventAttribute = 0;
|
||||
}
|
||||
fprintf(Efile,
|
||||
"struct %s %s%s;\n\n", o->obj_struc, EV_PREFIX, o->obj_name);
|
||||
}
|
||||
fprintf(Efile, "#define %s 0x%x\n", o->obj_name, o->obj_number);
|
||||
IFDEBUG(X)
|
||||
fprintf(astringfile, "\"%s(0x%x)\",\n", o->obj_name, o->obj_number);
|
||||
ENDDEBUG
|
||||
}
|
||||
IFDEBUG(o)
|
||||
fprintf(OUT, "insert(%s)\n", OBJ_NAME(o) );
|
||||
if(o->obj_right != NULL) {
|
||||
fprintf(OUT, "insert: unclean Object right\n");
|
||||
exit(-1);
|
||||
}
|
||||
if(o->obj_left != NULL) {
|
||||
fprintf(OUT, "insert: unclean Object left\n");
|
||||
exit(-1);
|
||||
}
|
||||
fflush(OUT);
|
||||
ENDDEBUG
|
||||
|
||||
while( val ) {
|
||||
if(p == NULL) {
|
||||
*q = o;
|
||||
o->obj_parent = (struct Object *)q;
|
||||
break;
|
||||
}
|
||||
if(!(val = strcmp(o->obj_name, p->obj_name)) ) {
|
||||
/* equal */
|
||||
fprintf(stderr, "re-inserting %s\n",o->obj_name);
|
||||
exit(-1);
|
||||
}
|
||||
if(val < 0) {
|
||||
/* left */
|
||||
q = &p->obj_left;
|
||||
p = p->obj_left;
|
||||
} else {
|
||||
/* right */
|
||||
q = &p->obj_right;
|
||||
p = p->obj_right;
|
||||
}
|
||||
}
|
||||
IFDEBUG(a)
|
||||
dumptree(Objtree,0);
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
delete(o)
|
||||
struct Object *o;
|
||||
{
|
||||
register struct Object *p = o->obj_right;
|
||||
register struct Object *q;
|
||||
register struct Object *newparent;
|
||||
register struct Object **np_childlink;
|
||||
|
||||
IFDEBUG(T)
|
||||
fprintf(stdout, "delete(0x%x)\n", o);
|
||||
dumptree(Objtree,0);
|
||||
ENDDEBUG
|
||||
|
||||
/* q <== lowest valued node of the right subtree */
|
||||
while( p ) {
|
||||
q = p;
|
||||
p = p->obj_left;
|
||||
}
|
||||
|
||||
if (o->obj_parent == (struct Object *)&Objtree) {
|
||||
newparent = (struct Object *)&Objtree;
|
||||
np_childlink = (struct Object **)&Objtree;
|
||||
} else if(o->obj_parent->obj_left == o) {
|
||||
newparent = o->obj_parent;
|
||||
np_childlink = &(o->obj_parent->obj_left);
|
||||
} else {
|
||||
newparent = o->obj_parent;
|
||||
np_childlink = &(o->obj_parent->obj_right);
|
||||
}
|
||||
IFDEBUG(T)
|
||||
fprintf(OUT, "newparent=0x%x\n");
|
||||
ENDDEBUG
|
||||
|
||||
if (q) { /* q gets the left, parent gets the right */
|
||||
IFDEBUG(T)
|
||||
fprintf(OUT, "delete: q null\n");
|
||||
ENDDEBUG
|
||||
q->obj_left = p;
|
||||
if(p) p->obj_parent = q;
|
||||
p = o->obj_right;
|
||||
} else { /* parent(instead of q) gets the left ; there is no right */
|
||||
IFDEBUG(T)
|
||||
fprintf(OUT, "delete: q not null\n");
|
||||
ENDDEBUG
|
||||
p = o->obj_left;
|
||||
}
|
||||
*np_childlink = p;
|
||||
if(p)
|
||||
p->obj_parent = newparent;
|
||||
|
||||
IFDEBUG(T)
|
||||
fprintf(OUT, "After deleting 0x%x\n",o);
|
||||
dumptree(Objtree,0);
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
struct Object *
|
||||
defineset(type, adr, keep)
|
||||
unsigned char type;
|
||||
char *adr;
|
||||
int keep;
|
||||
{
|
||||
struct Object *onew;
|
||||
IFDEBUG(o)
|
||||
printf("defineset(0x%x,%s, %s)\n", type , adr, keep?"KEEP":"NO_KEEP");
|
||||
ENDDEBUG
|
||||
|
||||
onew = (struct Object *)Malloc(sizeof (struct Object));
|
||||
bzero(onew, sizeof(struct Object));
|
||||
onew->obj_name = adr;
|
||||
onew->obj_kind = OBJ_SET;
|
||||
onew->obj_type = type;
|
||||
if(keep)
|
||||
insert( onew );
|
||||
/* address already stashed before calling defineset */
|
||||
IFDEBUG(o)
|
||||
printf("defineset(0x%x,%s) returning 0x%x\n", type , adr, onew);
|
||||
dumptree(Objtree,0);
|
||||
ENDDEBUG
|
||||
return(onew);
|
||||
}
|
||||
|
||||
dumpit(o, s)
|
||||
char *o;
|
||||
char *s;
|
||||
{
|
||||
register int i;
|
||||
|
||||
IFDEBUG(o)
|
||||
fprintf(OUT, "object 0x%x, %s\n",o, s);
|
||||
for(i=0; i< sizeof(struct Object); i+=4) {
|
||||
fprintf(OUT, "0x%x: 0x%x 0x%x 0x%x 0x%x\n",
|
||||
*((int *)o), *o, *(o+1), *(o+2), *(o+3) );
|
||||
}
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
defineitem(type, adr, struc)
|
||||
unsigned char type;
|
||||
char *adr;
|
||||
char *struc;
|
||||
{
|
||||
struct Object *onew;
|
||||
IFDEBUG(o)
|
||||
printf("defineitem(0x%x, %s at 0x%x, %s)\n", type, adr, adr, struc);
|
||||
ENDDEBUG
|
||||
|
||||
if( onew = lookup( type, adr ) ) {
|
||||
fprintf(stderr,
|
||||
"Internal error at defineitem: trying to redefine obj type 0x%x, adr %s\n",
|
||||
type, adr);
|
||||
exit(-1);
|
||||
} else {
|
||||
onew = (struct Object *)Malloc(sizeof (struct Object));
|
||||
bzero(onew, sizeof(struct Object));
|
||||
onew->obj_name = stash(adr);
|
||||
onew->obj_kind = OBJ_ITEM;
|
||||
onew->obj_type = type;
|
||||
onew->obj_struc = struc?stash(struc):struc;
|
||||
insert( onew );
|
||||
}
|
||||
IFDEBUG(o)
|
||||
fprintf(OUT, "defineitem(0x%x, %s) returning 0x%x\n", type, adr, onew);
|
||||
ENDDEBUG
|
||||
}
|
||||
|
||||
member(o, adr)
|
||||
struct Object *o;
|
||||
char *adr;
|
||||
{
|
||||
struct Object *onew, *oold;
|
||||
IFDEBUG(o)
|
||||
printf("member(0x%x, %s)\n", o, adr);
|
||||
ENDDEBUG
|
||||
|
||||
oold = lookup( o->obj_type, adr );
|
||||
|
||||
onew = (struct Object *)Malloc(sizeof (struct Object));
|
||||
if( oold == NULL ) {
|
||||
extern int lineno;
|
||||
|
||||
fprintf(stderr,
|
||||
"Warning at line %d: set definition of %s causes definition of\n",
|
||||
lineno, OBJ_NAME(o));
|
||||
fprintf(stderr, "\t (previously undefined) member %s\n", adr);
|
||||
bzero(onew, sizeof(struct Object));
|
||||
onew->obj_name = stash(adr);
|
||||
onew->obj_kind = OBJ_ITEM;
|
||||
onew->obj_type = o->obj_type;
|
||||
onew->obj_members = NULL;
|
||||
insert( onew );
|
||||
} else {
|
||||
if(oold->obj_kind != OBJ_ITEM) {
|
||||
fprintf(stderr, "Sets cannot be members of sets; %s\n", adr);
|
||||
exit(-1);
|
||||
}
|
||||
bcopy(oold, onew, sizeof(struct Object));
|
||||
onew->obj_members = onew->obj_left = onew->obj_right = NULL;
|
||||
}
|
||||
onew->obj_members = o->obj_members;
|
||||
o->obj_members = onew;
|
||||
}
|
||||
|
||||
struct Object *Lookup(type, name)
|
||||
unsigned char type;
|
||||
char *name;
|
||||
{
|
||||
register struct Object *o = lookup(type,name);
|
||||
|
||||
if(o == NULL) {
|
||||
fprintf(stderr, "Trying to use undefined %s: %s\n",
|
||||
type==STATESET?"state":"event", name);
|
||||
Exit(-1);
|
||||
}
|
||||
return(o);
|
||||
}
|
||||
|
||||
AddCurrentEventName(x)
|
||||
register char **x;
|
||||
{
|
||||
register char *n = EV_PREFIX; ;
|
||||
|
||||
if( CurrentEvent == (struct Object *)0 ) {
|
||||
fprintf(stderr, "No event named! BARF!\n"); Exit(-1);
|
||||
}
|
||||
|
||||
if( ! CurrentEvent->obj_struc ) {
|
||||
fprintf(stderr, "No attributes for current event!\n"); Exit(-1);
|
||||
}
|
||||
|
||||
/* add prefix first */
|
||||
while(*n) {
|
||||
*(*x)++ = *n++;
|
||||
}
|
||||
|
||||
n = CurrentEvent->obj_name;
|
||||
|
||||
while(*n) {
|
||||
*(*x)++ = *n++;
|
||||
}
|
||||
}
|
||||
|
||||
dumptree(o,i)
|
||||
register struct Object *o;
|
||||
int i;
|
||||
{
|
||||
register int j;
|
||||
|
||||
if(o == NULL) {
|
||||
for(j=0; j<i; j++)
|
||||
fputc(' ', stdout);
|
||||
fprintf(stdout, "%3d NULL\n", i);
|
||||
} else {
|
||||
dumptree(o->obj_left, i+1);
|
||||
for(j=0; j<i; j++)
|
||||
fputc(' ', stdout);
|
||||
fprintf(stdout, "%3d 0x%x: %s\n", i,o, OBJ_NAME(o));
|
||||
dumptree(o->obj_right, i+1);
|
||||
}
|
||||
}
|
||||
|
||||
dump(c,a)
|
||||
{
|
||||
register int x = 8;
|
||||
int zero = 0;
|
||||
#include <sys/signal.h>
|
||||
|
||||
fprintf(stderr, "dump: c 0x%x, a 0x%x\n",c,a);
|
||||
|
||||
x = x/zero;
|
||||
kill(0, SIGQUIT);
|
||||
}
|
||||
|
||||
dump_trans( pred, oldstate, newstate, action, event )
|
||||
struct Object *oldstate, *newstate, *event;
|
||||
char *pred, *action;
|
||||
{
|
||||
extern int transno;
|
||||
struct Object *o;
|
||||
|
||||
fprintf(stdout, "\n%d: ", transno);
|
||||
#define dumpit(x)\
|
||||
if((x)->obj_kind == OBJ_SET) {\
|
||||
o = (x)->obj_members; fprintf( stdout, "[ " );\
|
||||
while(o) { fprintf(stdout, "%s ", o->obj_name); o = o->obj_members; }\
|
||||
fprintf( stdout, " ] ");\
|
||||
} else { fprintf(stdout, "%s ", (x)->obj_name); }
|
||||
|
||||
dumpit(newstate);
|
||||
fprintf(stdout, " <== ");
|
||||
dumpit(oldstate);
|
||||
dumpit(event);
|
||||
fprintf(stdout, "\n\t\t%s\n\t\t%s\n", pred?pred:"DEFAULT",
|
||||
action);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/sets.h,v 1.1.1.1 1994/05/24 10:07:44 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/sets.h,v $ */
|
||||
|
||||
#define MAXEVENTS 200
|
||||
#define MAXSTATES 200
|
||||
|
||||
#define STATESET 10
|
||||
#define EVENTSET 5
|
||||
|
||||
#define OBJ_ITEM 2
|
||||
#define OBJ_SET 3
|
||||
|
||||
struct Object {
|
||||
unsigned char obj_kind;
|
||||
unsigned char obj_type; /* state or event */
|
||||
char *obj_name;
|
||||
char *obj_struc;
|
||||
int obj_number;
|
||||
struct Object *obj_members; /* must be null for kind==item */
|
||||
/* for the tree */
|
||||
struct Object *obj_left;
|
||||
struct Object *obj_right;
|
||||
struct Object *obj_parent;
|
||||
} ;
|
||||
|
||||
extern char *Noname;
|
||||
|
||||
#define OBJ_NAME(o) (((o)->obj_name)?(o)->obj_name:Noname)
|
||||
|
||||
extern int Nevents, Nstates;
|
||||
int Eventshift;
|
||||
extern struct Object *CurrentEvent;
|
||||
|
||||
extern struct Object *Lookup();
|
||||
extern struct Object *defineset();
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/* $Header: test.trans,v 0.2 88/09/19 12:58:29 nhall Exp $
|
||||
*/
|
||||
*PROTOCOL test
|
||||
|
||||
*INCLUDE
|
||||
|
||||
{
|
||||
#include "test_def.h"
|
||||
}
|
||||
|
||||
*PCB test_pcbstruct SYNONYM P
|
||||
|
||||
*STATES
|
||||
|
||||
STATE_A
|
||||
STATE_B
|
||||
STATE_C
|
||||
ALL_STATES = [STATE_A, STATE_B, STATE_C]
|
||||
|
||||
*EVENTS { int ev_all; } SYNONYM E
|
||||
|
||||
EV_1 { char *ev1_char; }
|
||||
EV_2 { int ev2_int; char ev2_char; }
|
||||
EV_3
|
||||
EV_4 { struct blah *ev4_blahptr;
|
||||
unsigned int ev4_uint;
|
||||
int ev4_int;
|
||||
}
|
||||
|
||||
*TRANSITIONS
|
||||
|
||||
SAME <== [ STATE_A, STATE_B ] [ EV_1, EV_2, EV_3 ]
|
||||
( $E.ev_all > 0 )
|
||||
{
|
||||
if( $P.test_state == STATE_A )
|
||||
printf("state is STATE_A\n");
|
||||
else
|
||||
printf("state is STATE_B\n");
|
||||
printf("action first transition\n");
|
||||
}
|
||||
|
||||
;
|
||||
STATE_C <== [ STATE_A, STATE_B ] [ EV_1, EV_2, EV_3 ]
|
||||
DEFAULT
|
||||
{
|
||||
printf("default - transition 2\n");
|
||||
MACRO1( $P.test_pcbfield );
|
||||
}
|
||||
;
|
||||
|
||||
STATE_C <== [ STATE_A, STATE_B ] EV_4
|
||||
( $$.ev4_blahptr->blahfield & 0x1 )
|
||||
NULLACTION
|
||||
;
|
||||
|
||||
STATE_C <== ALL_STATES EV_4
|
||||
DEFAULT
|
||||
{
|
||||
printf("default - transition 4\n");
|
||||
printf("pcb is 0x%x, event is 0x%x \n", $P, $E);
|
||||
printf("ev4 values are : blahptr 0x%x uint 0x%x int 0x%x\n",
|
||||
$$.ev4_blahptr, $$.ev4_uint, $$.ev4_int);
|
||||
}
|
||||
;
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
struct blah {
|
||||
unsigned int blahfield;
|
||||
int dummyi;
|
||||
char dummyc;
|
||||
};
|
||||
|
||||
struct test_pcbstruct {
|
||||
int test_pcbfield;
|
||||
int test_state;
|
||||
};
|
||||
|
||||
#define MACRO1(arg) if(arg != 0) { printf("macro1\n"); }
|
||||
@@ -1,315 +0,0 @@
|
||||
{
|
||||
#include "main.h"
|
||||
#include "sets.h"
|
||||
#include <stdio.h>
|
||||
|
||||
extern FILE *eventfile_h, *actfile;
|
||||
}
|
||||
|
||||
*fmq
|
||||
|
||||
novocab
|
||||
nobnf
|
||||
nofirst
|
||||
nofollow
|
||||
noparsetable
|
||||
noerrortables
|
||||
nos
|
||||
noe
|
||||
|
||||
*terminals
|
||||
|
||||
ID 0 0 { char *address; }
|
||||
STRUCT 0 0
|
||||
SYNONYM 0 0
|
||||
PREDICATE 0 0 { char *address; }
|
||||
ACTION 0 0 { char *address; }
|
||||
/*
|
||||
FSTRING 0 0 { char *address; }
|
||||
*/
|
||||
PROTOCOL 0 0
|
||||
LBRACK 0 0
|
||||
RBRACK 0 0
|
||||
LANGLE 0 0
|
||||
EQUAL 0 0
|
||||
COMMA 0 0
|
||||
STAR 0 0
|
||||
EVENTS 0 0
|
||||
TRANSITIONS 0 0
|
||||
INCLUDE 0 0
|
||||
STATES 0 0
|
||||
SEMI 0 0
|
||||
PCB 0 0 { char *address; }
|
||||
DEFAULT 0 0
|
||||
NULLACTION 0 0
|
||||
SAME 0 0
|
||||
|
||||
*nonterminals
|
||||
|
||||
pcb { char *address; int isevent; }
|
||||
syn { int type; }
|
||||
setlist { struct Object *setnum; }
|
||||
setlisttail { struct Object *setnum; }
|
||||
part { unsigned char type; }
|
||||
parttail { unsigned char type; }
|
||||
partrest { unsigned char type; char *address; }
|
||||
setstruct { struct Object *object; }
|
||||
setdef { unsigned char type,keep; char *address; struct Object *object; }
|
||||
translist
|
||||
transition
|
||||
event { struct Object *object; }
|
||||
oldstate { struct Object *object; }
|
||||
newstate { struct Object *object; }
|
||||
predicatepart { char *string; }
|
||||
actionpart { char *string; struct Object *oldstate; struct Object *newstate; }
|
||||
|
||||
*productions
|
||||
|
||||
program ::=
|
||||
STAR PROTOCOL ID
|
||||
{
|
||||
if(strlen($ID.address) > 50 ) {
|
||||
fprintf(stderr,
|
||||
"Protocol name may not exceed 50 chars in length.\n");
|
||||
Exit(-1);
|
||||
}
|
||||
strcpy(protocol, $ID.address);
|
||||
openfiles(protocol);
|
||||
}
|
||||
STAR includelist
|
||||
PCB
|
||||
{
|
||||
$$pcb.isevent = 0;
|
||||
}
|
||||
pcb
|
||||
{
|
||||
fprintf(actfile, "\ntypedef %s %s%s;\n",
|
||||
$pcb[7].address,protocol, PCBNAME);
|
||||
$$syn.type = PCB_SYN;
|
||||
}
|
||||
syn
|
||||
STAR STATES { $$part.type = (unsigned char) STATESET; } part
|
||||
STAR { end_states(eventfile_h); } EVENTS
|
||||
{ $$pcb.isevent = 1; }
|
||||
pcb
|
||||
{
|
||||
fprintf(eventfile_h, "\t"); /* fmq gags on single chars */
|
||||
includecode(eventfile_h, $pcb[14].address);
|
||||
fprintf(eventfile_h, "\n"); /* fmq gags on single chars */
|
||||
$$syn.type = EVENT_SYN;
|
||||
}
|
||||
syn
|
||||
{
|
||||
$$part.type = (unsigned char)EVENTSET;
|
||||
}
|
||||
part
|
||||
STAR { end_events(); }
|
||||
TRANSITIONS
|
||||
{
|
||||
putincludes();
|
||||
putdriver(actfile, 9);
|
||||
}
|
||||
translist
|
||||
;
|
||||
pcb ::= STRUCT
|
||||
{ if($pcb.isevent) {
|
||||
fprintf(stderr,
|
||||
"Event is a list of objects enclosed by \"{}\"\n");
|
||||
Exit(-1);
|
||||
}
|
||||
fprintf(eventfile_h, "struct ");
|
||||
}
|
||||
ACTION { $pcb.address = $ACTION.address; }
|
||||
optsemi
|
||||
::= ACTION
|
||||
{ if( ! $pcb.isevent) {
|
||||
fprintf(stderr,
|
||||
"Pcb requires a type or structure definition.\"{}\"\n");
|
||||
Exit(-1);
|
||||
}
|
||||
$pcb.address = $ACTION.address;
|
||||
}
|
||||
optsemi
|
||||
::= ID { $pcb.address = $ID.address; } optsemi
|
||||
;
|
||||
|
||||
syn ::= SYNONYM ID { synonyms[$syn.type] = stash( $ID.address ); }
|
||||
::=
|
||||
;
|
||||
|
||||
optsemi ::= SEMI
|
||||
::=
|
||||
;
|
||||
includelist ::= INCLUDE ACTION { includecode(actfile, $ACTION.address);} STAR
|
||||
::=
|
||||
;
|
||||
part ::= ID
|
||||
{
|
||||
$$partrest.address = $ID.address;
|
||||
$$partrest.type = $part.type;
|
||||
}
|
||||
partrest
|
||||
{ $$parttail.type = $part.type; }
|
||||
parttail
|
||||
;
|
||||
parttail ::= { $$part.type = $parttail.type; } part
|
||||
::=
|
||||
;
|
||||
partrest ::= EQUAL
|
||||
{
|
||||
if( lookup( $partrest.type, $partrest.address ) ) {
|
||||
fprintf(stderr, "bnf:trying to redefine obj type 0x%x, adr %s\n",
|
||||
$partrest.type, $partrest.address);
|
||||
Exit(-1);
|
||||
}
|
||||
$$setdef.type = $partrest.type;
|
||||
$$setdef.address = stash( $partrest.address );
|
||||
$$setdef.keep = 1;
|
||||
} setdef { $$setstruct.object = $setdef.object; } setstruct
|
||||
|
||||
::= ACTION
|
||||
{
|
||||
defineitem($partrest.type,
|
||||
$partrest.address, $ACTION.address);
|
||||
}
|
||||
|
||||
::= {
|
||||
defineitem($partrest.type, $partrest.address, (char *)0);
|
||||
}
|
||||
;
|
||||
|
||||
setstruct ::= ACTION
|
||||
{
|
||||
if($setstruct.object) {
|
||||
/* WHEN COULD THIS BE FALSE??
|
||||
* isn't it supposed to be setstruct.object???
|
||||
* (it used to be $ACTION.address)
|
||||
*/
|
||||
|
||||
$setstruct.object->obj_struc = $ACTION.address;
|
||||
fprintf(eventfile_h,
|
||||
"struct %s %s%s;\n\n", $ACTION.address,
|
||||
EV_PREFIX, $setstruct.object->obj_name);
|
||||
}
|
||||
}
|
||||
::=
|
||||
;
|
||||
|
||||
setdef ::= LBRACK
|
||||
{
|
||||
$$setlist.setnum =
|
||||
defineset($setdef.type, $setdef.address, $setdef.keep);
|
||||
} setlist RBRACK { $setdef.object = $setlist.setnum; }
|
||||
;
|
||||
|
||||
setlist ::= ID
|
||||
{
|
||||
member($setlist.setnum, $ID.address);
|
||||
$$setlisttail.setnum = $setlist.setnum;
|
||||
} setlisttail
|
||||
;
|
||||
|
||||
setlisttail ::= COMMA { $$setlist.setnum = $setlisttail.setnum; } setlist
|
||||
::=
|
||||
;
|
||||
translist ::= transition translisttail
|
||||
;
|
||||
translisttail ::= translist
|
||||
::=
|
||||
;
|
||||
transition ::= newstate { transno ++; } LANGLE EQUAL EQUAL oldstate
|
||||
event
|
||||
{
|
||||
CurrentEvent /* GAG! */ = $event.object;
|
||||
}
|
||||
predicatepart
|
||||
{
|
||||
$$actionpart.string = $predicatepart.string;
|
||||
$$actionpart.newstate = $newstate.object;
|
||||
$$actionpart.oldstate = $oldstate.object;
|
||||
}
|
||||
actionpart
|
||||
SEMI
|
||||
;
|
||||
|
||||
predicatepart ::= PREDICATE
|
||||
{
|
||||
$predicatepart.string = stash ( $PREDICATE.address );
|
||||
}
|
||||
::= DEFAULT
|
||||
{
|
||||
$predicatepart.string = (char *)0;
|
||||
}
|
||||
;
|
||||
|
||||
actionpart ::=
|
||||
ACTION
|
||||
{
|
||||
statetable( $actionpart.string, $actionpart.oldstate,
|
||||
$actionpart.newstate,
|
||||
acttable(actfile, $ACTION.address ),
|
||||
CurrentEvent );
|
||||
if( print_trans ) {
|
||||
dump_trans( $actionpart.string, $actionpart.oldstate,
|
||||
$actionpart.newstate,
|
||||
$ACTION.address, CurrentEvent );
|
||||
}
|
||||
}
|
||||
::= NULLACTION
|
||||
{
|
||||
statetable($actionpart.string, $actionpart.oldstate, $actionpart.newstate,
|
||||
0, CurrentEvent ); /* KLUDGE - remove this */
|
||||
if( print_trans ) {
|
||||
dump_trans( $actionpart.string, $actionpart.oldstate,
|
||||
$actionpart.newstate,
|
||||
"NULLACTION", CurrentEvent );
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
oldstate ::= ID
|
||||
{
|
||||
$oldstate.object = Lookup(STATESET, $ID.address);
|
||||
}
|
||||
::= {
|
||||
$$setdef.address = (char *)0;
|
||||
$$setdef.type = (unsigned char)STATESET;
|
||||
$$setdef.keep = 0;
|
||||
}
|
||||
setdef
|
||||
{
|
||||
$oldstate.object = $setdef.object;
|
||||
}
|
||||
;
|
||||
|
||||
newstate ::= ID
|
||||
{
|
||||
$newstate.object = Lookup(STATESET, $ID.address);
|
||||
}
|
||||
;
|
||||
|
||||
newstate ::= SAME
|
||||
{
|
||||
extern struct Object *SameState;
|
||||
|
||||
$newstate.object = SameState;
|
||||
}
|
||||
;
|
||||
|
||||
event ::= ID
|
||||
{
|
||||
$event.object = Lookup(EVENTSET, $ID.address);
|
||||
}
|
||||
::=
|
||||
{
|
||||
$$setdef.address = (char *)0;
|
||||
$$setdef.type = (unsigned char)EVENTSET;
|
||||
$$setdef.keep = 0;
|
||||
}
|
||||
setdef
|
||||
{
|
||||
$event.object = $setdef.object;
|
||||
}
|
||||
;
|
||||
|
||||
*end
|
||||
@@ -1,451 +0,0 @@
|
||||
/* $Header: /home/ncvs/src/sys/netiso/xebec/xebec.c,v 1.1.1.1 1994/05/24 10:07:43 rgrimes Exp $ */
|
||||
/* $Source: /home/ncvs/src/sys/netiso/xebec/xebec.c,v $ */
|
||||
|
||||
#include "xebec.h"
|
||||
#include "llparse.h"
|
||||
#ifndef E_TABLE
|
||||
#define E_TABLE "xebec.e"
|
||||
#endif E_TABLE
|
||||
|
||||
#include "main.h"
|
||||
#include "sets.h"
|
||||
#include <stdio.h>
|
||||
|
||||
extern FILE *eventfile_h, *actfile;
|
||||
|
||||
llaction(lln,token)
|
||||
LLtoken *token;
|
||||
{
|
||||
struct llattr *llattr;
|
||||
llattr = &llattrdesc[lldescindex-1];
|
||||
switch(lln) {
|
||||
case 1:
|
||||
llfinprod();
|
||||
break;
|
||||
|
||||
case 10: {
|
||||
|
||||
if(strlen(llattr->llabase[3].ID.address) > 50 ) {
|
||||
fprintf(stderr,
|
||||
"Protocol name may not exceed 50 chars in length.\n");
|
||||
Exit(-1);
|
||||
}
|
||||
strcpy(protocol, llattr->llabase[3].ID.address);
|
||||
openfiles(protocol);
|
||||
|
||||
} break;
|
||||
|
||||
case 11: {
|
||||
|
||||
llattr->llabase[7].pcb.isevent = 0;
|
||||
|
||||
} break;
|
||||
|
||||
case 12: {
|
||||
|
||||
fprintf(actfile, "\ntypedef %s %s%s;\n",
|
||||
llattr->llabase[7].pcb.address,protocol, PCBNAME);
|
||||
llattr->llabase[8].syn.type = PCB_SYN;
|
||||
|
||||
} break;
|
||||
|
||||
case 13: {
|
||||
llattr->llabase[11].part.type = (unsigned char) STATESET;
|
||||
} break;
|
||||
|
||||
case 14: {
|
||||
end_states(eventfile_h);
|
||||
} break;
|
||||
|
||||
case 15: {
|
||||
llattr->llabase[14].pcb.isevent = 1;
|
||||
} break;
|
||||
|
||||
case 16: {
|
||||
|
||||
fprintf(eventfile_h, "\t"); /* fmq gags on single chars */
|
||||
includecode(eventfile_h, llattr->llabase[14].pcb.address);
|
||||
fprintf(eventfile_h, "\n"); /* fmq gags on single chars */
|
||||
llattr->llabase[15].syn.type = EVENT_SYN;
|
||||
|
||||
} break;
|
||||
|
||||
case 17: {
|
||||
|
||||
llattr->llabase[16].part.type = (unsigned char)EVENTSET;
|
||||
|
||||
} break;
|
||||
|
||||
case 18: {
|
||||
end_events();
|
||||
} break;
|
||||
|
||||
case 19: {
|
||||
|
||||
putincludes();
|
||||
putdriver(actfile, 9);
|
||||
|
||||
} break;
|
||||
|
||||
case 20: {
|
||||
if(llattr->llabase[0].pcb.isevent) {
|
||||
fprintf(stderr,
|
||||
"Event is a list of objects enclosed by \"{}\"\n");
|
||||
Exit(-1);
|
||||
}
|
||||
fprintf(eventfile_h, "struct ");
|
||||
|
||||
} break;
|
||||
|
||||
case 21: {
|
||||
llattr->llabase[0].pcb.address = llattr->llabase[2].ACTION.address;
|
||||
} break;
|
||||
|
||||
case 22: {
|
||||
if( ! llattr->llabase[0].pcb.isevent) {
|
||||
fprintf(stderr,
|
||||
"Pcb requires a type or structure definition.\"{}\"\n");
|
||||
Exit(-1);
|
||||
}
|
||||
llattr->llabase[0].pcb.address = llattr->llabase[1].ACTION.address;
|
||||
|
||||
} break;
|
||||
|
||||
case 23: {
|
||||
llattr->llabase[0].pcb.address = llattr->llabase[1].ID.address;
|
||||
} break;
|
||||
|
||||
case 24: {
|
||||
synonyms[llattr->llabase[0].syn.type] = stash( llattr->llabase[2].ID.address );
|
||||
} break;
|
||||
|
||||
case 25: {
|
||||
includecode(actfile, llattr->llabase[2].ACTION.address);
|
||||
} break;
|
||||
|
||||
case 26: {
|
||||
|
||||
llattr->llabase[2].partrest.address = llattr->llabase[1].ID.address;
|
||||
llattr->llabase[2].partrest.type = llattr->llabase[0].part.type;
|
||||
|
||||
} break;
|
||||
|
||||
case 27: {
|
||||
llattr->llabase[3].parttail.type = llattr->llabase[0].part.type;
|
||||
} break;
|
||||
|
||||
case 28: {
|
||||
llattr->llabase[1].part.type = llattr->llabase[0].parttail.type;
|
||||
} break;
|
||||
|
||||
case 29: {
|
||||
|
||||
if( lookup( llattr->llabase[0].partrest.type, llattr->llabase[0].partrest.address ) ) {
|
||||
fprintf(stderr, "bnf:trying to redefine obj type 0x%x, adr %s\n",
|
||||
llattr->llabase[0].partrest.type, llattr->llabase[0].partrest.address);
|
||||
Exit(-1);
|
||||
}
|
||||
llattr->llabase[2].setdef.type = llattr->llabase[0].partrest.type;
|
||||
llattr->llabase[2].setdef.address = stash( llattr->llabase[0].partrest.address );
|
||||
llattr->llabase[2].setdef.keep = 1;
|
||||
|
||||
} break;
|
||||
|
||||
case 30: {
|
||||
llattr->llabase[3].setstruct.object = llattr->llabase[2].setdef.object;
|
||||
} break;
|
||||
|
||||
case 31: {
|
||||
|
||||
defineitem(llattr->llabase[0].partrest.type,
|
||||
llattr->llabase[0].partrest.address, llattr->llabase[1].ACTION.address);
|
||||
|
||||
} break;
|
||||
|
||||
case 32: {
|
||||
|
||||
defineitem(llattr->llabase[0].partrest.type, llattr->llabase[0].partrest.address, (char *)0);
|
||||
|
||||
} break;
|
||||
|
||||
case 33: {
|
||||
|
||||
if(llattr->llabase[0].setstruct.object) {
|
||||
/* WHEN COULD THIS BE FALSE??
|
||||
* isn't it supposed to be setstruct.object???
|
||||
* (it used to be $ACTION.address)
|
||||
*/
|
||||
|
||||
llattr->llabase[0].setstruct.object->obj_struc = llattr->llabase[1].ACTION.address;
|
||||
fprintf(eventfile_h,
|
||||
"struct %s %s%s;\n\n", llattr->llabase[1].ACTION.address,
|
||||
EV_PREFIX, llattr->llabase[0].setstruct.object->obj_name);
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case 34: {
|
||||
|
||||
llattr->llabase[2].setlist.setnum =
|
||||
defineset(llattr->llabase[0].setdef.type, llattr->llabase[0].setdef.address, llattr->llabase[0].setdef.keep);
|
||||
|
||||
} break;
|
||||
|
||||
case 35: {
|
||||
llattr->llabase[0].setdef.object = llattr->llabase[2].setlist.setnum;
|
||||
} break;
|
||||
|
||||
case 36: {
|
||||
|
||||
member(llattr->llabase[0].setlist.setnum, llattr->llabase[1].ID.address);
|
||||
llattr->llabase[2].setlisttail.setnum = llattr->llabase[0].setlist.setnum;
|
||||
|
||||
} break;
|
||||
|
||||
case 37: {
|
||||
llattr->llabase[2].setlist.setnum = llattr->llabase[0].setlisttail.setnum;
|
||||
} break;
|
||||
|
||||
case 38: {
|
||||
transno ++;
|
||||
} break;
|
||||
|
||||
case 39: {
|
||||
|
||||
CurrentEvent /* GAG! */ = llattr->llabase[6].event.object;
|
||||
|
||||
} break;
|
||||
|
||||
case 40: {
|
||||
|
||||
llattr->llabase[8].actionpart.string = llattr->llabase[7].predicatepart.string;
|
||||
llattr->llabase[8].actionpart.newstate = llattr->llabase[1].newstate.object;
|
||||
llattr->llabase[8].actionpart.oldstate = llattr->llabase[5].oldstate.object;
|
||||
|
||||
} break;
|
||||
|
||||
case 41: {
|
||||
|
||||
llattr->llabase[0].predicatepart.string = stash ( llattr->llabase[1].PREDICATE.address );
|
||||
|
||||
} break;
|
||||
|
||||
case 42: {
|
||||
|
||||
llattr->llabase[0].predicatepart.string = (char *)0;
|
||||
|
||||
} break;
|
||||
|
||||
case 43: {
|
||||
|
||||
statetable( llattr->llabase[0].actionpart.string, llattr->llabase[0].actionpart.oldstate,
|
||||
llattr->llabase[0].actionpart.newstate,
|
||||
acttable(actfile, llattr->llabase[1].ACTION.address ),
|
||||
CurrentEvent );
|
||||
if( print_trans ) {
|
||||
dump_trans( llattr->llabase[0].actionpart.string, llattr->llabase[0].actionpart.oldstate,
|
||||
llattr->llabase[0].actionpart.newstate,
|
||||
llattr->llabase[1].ACTION.address, CurrentEvent );
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case 44: {
|
||||
|
||||
statetable(llattr->llabase[0].actionpart.string, llattr->llabase[0].actionpart.oldstate, llattr->llabase[0].actionpart.newstate,
|
||||
0, CurrentEvent ); /* KLUDGE - remove this */
|
||||
if( print_trans ) {
|
||||
dump_trans( llattr->llabase[0].actionpart.string, llattr->llabase[0].actionpart.oldstate,
|
||||
llattr->llabase[0].actionpart.newstate,
|
||||
"NULLACTION", CurrentEvent );
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case 45: {
|
||||
|
||||
llattr->llabase[0].oldstate.object = Lookup(STATESET, llattr->llabase[1].ID.address);
|
||||
|
||||
} break;
|
||||
|
||||
case 46: {
|
||||
|
||||
llattr->llabase[1].setdef.address = (char *)0;
|
||||
llattr->llabase[1].setdef.type = (unsigned char)STATESET;
|
||||
llattr->llabase[1].setdef.keep = 0;
|
||||
|
||||
} break;
|
||||
|
||||
case 47: {
|
||||
|
||||
llattr->llabase[0].oldstate.object = llattr->llabase[1].setdef.object;
|
||||
|
||||
} break;
|
||||
|
||||
case 48: {
|
||||
|
||||
llattr->llabase[0].newstate.object = Lookup(STATESET, llattr->llabase[1].ID.address);
|
||||
|
||||
} break;
|
||||
|
||||
case 49: {
|
||||
|
||||
extern struct Object *SameState;
|
||||
|
||||
llattr->llabase[0].newstate.object = SameState;
|
||||
|
||||
} break;
|
||||
|
||||
case 50: {
|
||||
|
||||
llattr->llabase[0].event.object = Lookup(EVENTSET, llattr->llabase[1].ID.address);
|
||||
|
||||
} break;
|
||||
|
||||
case 51: {
|
||||
|
||||
llattr->llabase[1].setdef.address = (char *)0;
|
||||
llattr->llabase[1].setdef.type = (unsigned char)EVENTSET;
|
||||
llattr->llabase[1].setdef.keep = 0;
|
||||
|
||||
} break;
|
||||
|
||||
case 52: {
|
||||
|
||||
llattr->llabase[0].event.object = llattr->llabase[1].setdef.object;
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
char *llstrings[] = {
|
||||
"<null>",
|
||||
"ID",
|
||||
"STRUCT",
|
||||
"SYNONYM",
|
||||
"PREDICATE",
|
||||
"ACTION",
|
||||
"PROTOCOL",
|
||||
"LBRACK",
|
||||
"RBRACK",
|
||||
"LANGLE",
|
||||
"EQUAL",
|
||||
"COMMA",
|
||||
"STAR",
|
||||
"EVENTS",
|
||||
"TRANSITIONS",
|
||||
"INCLUDE",
|
||||
"STATES",
|
||||
"SEMI",
|
||||
"PCB",
|
||||
"DEFAULT",
|
||||
"NULLACTION",
|
||||
"SAME",
|
||||
"ENDMARKER",
|
||||
"pcb",
|
||||
"syn",
|
||||
"setlist",
|
||||
"setlisttail",
|
||||
"part",
|
||||
"parttail",
|
||||
"partrest",
|
||||
"setstruct",
|
||||
"setdef",
|
||||
"translist",
|
||||
"transition",
|
||||
"event",
|
||||
"oldstate",
|
||||
"newstate",
|
||||
"predicatepart",
|
||||
"actionpart",
|
||||
"program",
|
||||
"includelist",
|
||||
"optsemi",
|
||||
"translisttail",
|
||||
"$goal$",
|
||||
(char *) 0
|
||||
};
|
||||
short llnterms = 23;
|
||||
short llnsyms = 44;
|
||||
short llnprods = 38;
|
||||
short llinfinite = 10000;
|
||||
short llproductions[] = {
|
||||
41, -21, 5, -20, 2,
|
||||
41, -22, 5,
|
||||
41, -23, 1,
|
||||
-24, 1, 3,
|
||||
|
||||
26, -36, 1,
|
||||
25, -37, 11,
|
||||
|
||||
28, -27, 29, -26, 1,
|
||||
27, -28,
|
||||
|
||||
30, -30, 31, -29, 10,
|
||||
-31, 5,
|
||||
-32,
|
||||
-33, 5,
|
||||
|
||||
-35, 8, 25, -34, 7,
|
||||
42, 33,
|
||||
17, 38, -40, 37, -39, 34, 35, 10, 10, 9, -38, 36,
|
||||
-50, 1,
|
||||
-52, 31, -51,
|
||||
-45, 1,
|
||||
-47, 31, -46,
|
||||
-48, 1,
|
||||
-49, 21,
|
||||
-41, 4,
|
||||
-42, 19,
|
||||
-43, 5,
|
||||
-44, 20,
|
||||
32, -19, 14, -18, 12, 27, -17, 24, -16, 23, -15, 13, -14, 12, 27, -13, 16, 12, 24, -12, 23, -11, 18, 40, 12, -10, 1, 6, 12,
|
||||
12, -25, 5, 15,
|
||||
|
||||
17,
|
||||
|
||||
32,
|
||||
|
||||
22, 39,
|
||||
0
|
||||
};
|
||||
struct llprodindex llprodindex[] = {
|
||||
{ 0, 0, 0 }, { 0, 5, 19 }, { 5, 3, 3 }, { 8, 3, 2 },
|
||||
{ 11, 3, 2 }, { 14, 0, 2 }, { 14, 3, 0 }, { 17, 3, 1 },
|
||||
{ 20, 0, 0 }, { 20, 5, 3 }, { 25, 2, 0 }, { 27, 0, 3 },
|
||||
{ 27, 5, 1 }, { 32, 2, 0 }, { 34, 1, 3 }, { 35, 2, 1 },
|
||||
{ 37, 0, 0 }, { 37, 5, 1 }, { 42, 2, 0 }, { 44, 12, 3 },
|
||||
{ 56, 2, 2 }, { 58, 3, 2 }, { 61, 2, 0 }, { 63, 3, 2 },
|
||||
{ 66, 2, 1 }, { 68, 2, 0 }, { 70, 2, 9 }, { 72, 2, 1 },
|
||||
{ 74, 2, 1 }, { 76, 2, 1 }, { 78, 29, 1 }, { 107, 4, 1 },
|
||||
{ 111, 0, 1 }, { 111, 1, 1 }, { 112, 0, 1 }, { 112, 1, 1 },
|
||||
{ 113, 0, 1 }, { 113, 2, 2 }, { 0, 0, 0 }
|
||||
};
|
||||
short llepsilon[] = {
|
||||
0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
|
||||
0, 1, 0, 0, 1, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 1, 0, 1, 0, 0
|
||||
};
|
||||
struct llparsetable llparsetable[] = {
|
||||
{ 1, 3 }, { 2, 1 }, { 5, 2 }, { 0, 23 }, { 1, 5 },
|
||||
{ 3, 4 }, { 12, 5 }, { 0, 24 }, { 1, 6 }, { 0, 25 },
|
||||
{ 8, 8 }, { 11, 7 }, { 0, 26 }, { 1, 9 }, { 0, 27 },
|
||||
{ 1, 10 }, { 12, 11 }, { 0, 28 }, { 1, 14 }, { 5, 13 },
|
||||
{ 10, 12 }, { 12, 14 }, { 0, 29 }, { 1, 16 }, { 5, 15 },
|
||||
{ 12, 16 }, { 0, 30 }, { 7, 17 }, { 0, 31 }, { 1, 18 },
|
||||
{ 21, 18 }, { 0, 32 }, { 1, 19 }, { 21, 19 }, { 0, 33 },
|
||||
{ 1, 20 }, { 7, 21 }, { 0, 34 }, { 1, 22 }, { 7, 23 },
|
||||
{ 0, 35 }, { 1, 24 }, { 21, 25 }, { 0, 36 }, { 4, 26 },
|
||||
{ 19, 27 }, { 0, 37 }, { 5, 28 }, { 20, 29 }, { 0, 38 },
|
||||
{ 12, 30 }, { 0, 39 }, { 15, 31 }, { 18, 32 }, { 0, 40 },
|
||||
{ 1, 34 }, { 3, 34 }, { 12, 34 }, { 17, 33 }, { 0, 41 },
|
||||
{ 1, 35 }, { 21, 35 }, { 22, 36 }, { 0, 42 }, { 12, 37 },
|
||||
{ 0, 43 }, { 0, 0 }
|
||||
};
|
||||
short llparseindex[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 4, 8, 10, 13, 15, 18,
|
||||
23, 27, 29, 32, 35, 38, 41, 44, 47, 50,
|
||||
52, 55, 60, 64, 0
|
||||
};
|
||||
@@ -1,88 +0,0 @@
|
||||
/* $Header: xebec.h,v 2.1 88/09/19 12:56:35 nhall Exp $ */
|
||||
/* $Source: /var/home/tadl/src/argo/xebec/RCS/xebec.h,v $ */
|
||||
|
||||
union llattrib {
|
||||
struct {
|
||||
char *address; } ID;
|
||||
int STRUCT;
|
||||
int SYNONYM;
|
||||
struct {
|
||||
char *address; } PREDICATE;
|
||||
struct {
|
||||
char *address; } ACTION;
|
||||
int PROTOCOL;
|
||||
int LBRACK;
|
||||
int RBRACK;
|
||||
int LANGLE;
|
||||
int EQUAL;
|
||||
int COMMA;
|
||||
int STAR;
|
||||
int EVENTS;
|
||||
int TRANSITIONS;
|
||||
int INCLUDE;
|
||||
int STATES;
|
||||
int SEMI;
|
||||
struct {
|
||||
char *address; } PCB;
|
||||
int DEFAULT;
|
||||
int NULLACTION;
|
||||
int SAME;
|
||||
struct {
|
||||
char *address; int isevent; } pcb;
|
||||
struct {
|
||||
int type; } syn;
|
||||
struct {
|
||||
struct Object *setnum; } setlist;
|
||||
struct {
|
||||
struct Object *setnum; } setlisttail;
|
||||
struct {
|
||||
unsigned char type; } part;
|
||||
struct {
|
||||
unsigned char type; } parttail;
|
||||
struct {
|
||||
unsigned char type; char *address; } partrest;
|
||||
struct {
|
||||
struct Object *object; } setstruct;
|
||||
struct {
|
||||
unsigned char type,keep; char *address; struct Object *object; } setdef;
|
||||
int translist;
|
||||
int transition;
|
||||
struct {
|
||||
struct Object *object; } event;
|
||||
struct {
|
||||
struct Object *object; } oldstate;
|
||||
struct {
|
||||
struct Object *object; } newstate;
|
||||
struct {
|
||||
char *string; } predicatepart;
|
||||
struct {
|
||||
char *string; struct Object *oldstate; struct Object *newstate; } actionpart;
|
||||
};
|
||||
#define LLTERM 23
|
||||
#define LLSYM 44
|
||||
#define LLPROD 38
|
||||
|
||||
#define LLINF 10000
|
||||
|
||||
#define T_ID 1
|
||||
#define T_STRUCT 2
|
||||
#define T_SYNONYM 3
|
||||
#define T_PREDICATE 4
|
||||
#define T_ACTION 5
|
||||
#define T_PROTOCOL 6
|
||||
#define T_LBRACK 7
|
||||
#define T_RBRACK 8
|
||||
#define T_LANGLE 9
|
||||
#define T_EQUAL 10
|
||||
#define T_COMMA 11
|
||||
#define T_STAR 12
|
||||
#define T_EVENTS 13
|
||||
#define T_TRANSITIONS 14
|
||||
#define T_INCLUDE 15
|
||||
#define T_STATES 16
|
||||
#define T_SEMI 17
|
||||
#define T_PCB 18
|
||||
#define T_DEFAULT 19
|
||||
#define T_NULLACTION 20
|
||||
#define T_SAME 21
|
||||
#define T_ENDMARKER 22
|
||||
Reference in New Issue
Block a user