Get rid of netiso. It hasn't compiled in some time, there are no

applications, and nobody uses it.
This commit is contained in:
Garrett Wollman
1996-02-06 21:02:09 +00:00
parent bba9a7a06b
commit 8df32b19de
86 changed files with 0 additions and 31496 deletions
-298
View File
@@ -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
-70
View File
@@ -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
-469
View File
@@ -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
-260
View File
@@ -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 */
-377
View File
@@ -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);
}
-860
View File
@@ -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 */
-556
View File
@@ -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 */
-533
View File
@@ -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 */
-563
View File
@@ -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()
{
}
-353
View File
@@ -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);
}
-103
View File
@@ -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
-659
View File
@@ -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 */
-182
View File
@@ -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);
}
-407
View File
@@ -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);
}
-60
View File
@@ -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
-98
View File
@@ -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
-199
View File
@@ -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
-176
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
-141
View File
@@ -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
-178
View File
@@ -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);
}
-961
View File
@@ -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 */
-608
View File
@@ -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
-919
View File
@@ -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 */
-198
View File
@@ -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
-361
View File
@@ -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;
}
-275
View File
@@ -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
-618
View File
@@ -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 */
-119
View File
@@ -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
-201
View File
@@ -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 */
-739
View File
@@ -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((&gte_dl), snpa, snpalen, index);
gte_dl.sdl_type = iftype;
if (rtrequest(RTM_ADD, S(dst), S(gte_dl), netmask, flags, &mrt) ||
mrt == 0)
return (0);
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 */
-120
View File
@@ -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
-146
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
-75
View File
@@ -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)",
};
-94
View File
@@ -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
-310
View File
@@ -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 */
-997
View File
@@ -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;
}
-997
View File
@@ -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;
}
}
-91
View File
@@ -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
-691
View File
@@ -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
-91
View File
@@ -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
-694
View File
@@ -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 */
-128
View File
@@ -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 */
-99
View File
@@ -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
-714
View File
@@ -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;
}
-367
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
-359
View File
@@ -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
-125
View File
@@ -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
-284
View File
@@ -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
-20
View File
@@ -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
-75
View File
@@ -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},
-949
View File
@@ -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");
}
}
-882
View File
@@ -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 */
-378
View File
@@ -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
-94
View File
@@ -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
-297
View File
@@ -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
-177
View File
@@ -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 */
-196
View File
@@ -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
-163
View File
@@ -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
-758
View File
@@ -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;
}
-349
View File
@@ -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>
-144
View File
@@ -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);
}
-65
View File
@@ -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
-313
View File
@@ -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));
}
-8
View File
@@ -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>
-22
View File
@@ -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
-366
View File
@@ -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
}
-145
View File
@@ -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();
-430
View File
@@ -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);
}
}
-410
View File
@@ -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);
*/
}
-32
View File
@@ -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();
-136
View File
@@ -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);
}
-4
View File
@@ -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();
-437
View File
@@ -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
-5
View File
@@ -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;
-244
View File
@@ -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
}
-472
View File
@@ -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);
}
-36
View File
@@ -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();
-64
View File
@@ -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);
}
;
-13
View File
@@ -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"); }
-315
View File
@@ -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
-451
View File
@@ -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
};
-88
View File
@@ -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