V8/usr/sys/chaos/chaos.h
#ifndef _CHAOS_
#define _CHAOS_
/*
* Accomodate Ritchie C compiler...
*/
#ifdef pdp11
#ifndef lint
#ifndef void
#define void int
#endif
#endif
#endif
#include "../chaos/constants.h"
/*
* System and device independent include file for the Chaosnet NCP
*/
/*
* A chaos index - a hosts connection identifier
*/
typedef union {
unsigned short ci_idx; /* Index as a whole */
struct {
unsigned char ci_Tidx; /* Connection table index */
unsigned char ci_Uniq; /* Uniquizer for table slot */
} ci_bytes;
} chindex;
#define ci_uniq ci_bytes.ci_Uniq
#define ci_tidx ci_bytes.ci_Tidx
/*
* A chaos network address.
*/
typedef union {
unsigned short ch_addr; /* Address as a whole */
struct {
unsigned char ch_Host; /* Host number on subnet */
unsigned char ch_Subnet; /* Subnet number */
} ch_bytes;
} chaddr;
#define ch_subnet ch_bytes.ch_Subnet
#define ch_host ch_bytes.ch_Host
/*
* A chaosnet clock time - wrapsaround
*/
typedef unsigned short chtime;
/*
* This is the part of the packet which is only for use by the ncp.
* It is not transmitted over the network
* NOTE that this structure is assumed to be at least 8 bytes by
* the Interlan Ethernet driver, and assumed to be at most 8 bytes
* by the storage allocator!!!!! GGAAAAAAAAAAAGGGHHH
*/
struct ncp_header {
struct packet *nh_next; /* Link to next packet on this list */
chtime nh_time; /* Last time packet was processed */
chaddr nh_xdest; /* Routed destination address */
};
/*
* This is the part of the packet header that is transmitted over the
* network, thus must have fixed, portable format from ncp to ncp
*/
struct pkt_header {
unsigned char ph_type; /* Protocol type */
unsigned char ph_op; /* Opcode of the packet */
union {
unsigned short ph_lfcwhole;
struct {
unsigned short ph_Len:12; /* Length of packet */
unsigned short ph_fcount:4; /* Forwarding count */
} ph_lfcparts;
} ph_lenfc;
chaddr ph_daddr; /* Destination address */
chindex ph_didx; /* Destination index */
chaddr ph_saddr; /* Source address */
chindex ph_sidx; /* Source index */
unsigned short ph_pkn; /* Packet number */
unsigned short ph_ackn; /* Acknowledged packet number */
};
#define ph_len ph_lenfc.ph_lfcparts.ph_Len
/* This is the actual structure of a packet in core */
struct packet {
struct ncp_header pk_nhead; /* NCP specific information */
struct pkt_header pk_phead; /* Network header */
union {
char pk_Cdata[sizeof(short)];/* Character data */
short pk_Idata[1]; /* word data */
long pk_Ldata[1]; /* long data */
struct sts_data { /* data of STS packets */
unsigned short pk_Receipt;
unsigned short pk_Rwsize;
} pk_stsdata;
struct rut_data { /* data of RUT packets */
unsigned short pk_subnet;
unsigned short pk_cost;
} pk_Rutdata[1];
struct status {
#define CHSTNAME 32
char sb_name[CHSTNAME];
struct statdata {
struct stathead {
unsigned short sb_Ident;
unsigned short sb_Nshorts;
} sb_head;
union {
struct statxcvr {
long sx_Rcvd;
long sx_Xmtd;
long sx_Abrt;
long sx_Lost;
long sx_Crcr;
long sx_Crci;
long sx_Leng;
long sx_Rej;
} sb_Xstat;
} sb_union;
} sb_data[1];
} pk_Status;
} pk_data;
};
#define NOPKT ((struct packet *)0)
#define CHHEADSIZE (sizeof(struct ncp_header)+sizeof(struct pkt_header))
#define pkalloc(x,y) ((struct packet *)ch_alloc((x)+CHHEADSIZE,(y)))
/*
* Allocate an NCP packet given the number of shorts in the received packet.
*/
#define hpkalloc(nshorts) ((struct packet *)ch_alloc((int) \
((nshorts) /* * sizeof(short) */ << 1) + \
sizeof(struct ncp_header), 1))
/* macros for accessing packets fields */
#define pk_next pk_nhead.nh_next
#define pk_time pk_nhead.nh_time
#define pk_xdest pk_nhead.nh_xdest.ch_addr
#define pk_type pk_phead.ph_type
#define pk_op pk_phead.ph_op
#define pk_len pk_phead.ph_len
#define pk_fc pk_phead.ph_lenfc.ph_lfcparts.ph_fcount
#define pk_lenword pk_phead.ph_lenfc.ph_lfcwhole
#define pk_daddr pk_phead.ph_daddr.ch_addr
#define pk_dhost pk_phead.ph_daddr.ch_host
#define pk_dsubnet pk_phead.ph_daddr.ch_subnet
#define pk_didx pk_phead.ph_didx.ci_idx
#define pk_dtindex pk_phead.ph_didx.ci_tidx
#define pk_saddr pk_phead.ph_saddr.ch_addr
#define pk_shost pk_phead.ph_saddr.ch_host
#define pk_ssubnet pk_phead.ph_saddr.ch_subnet
#define pk_sidx pk_phead.ph_sidx.ci_idx
#define pk_stindex pk_phead.ph_sidx.ci_tidx
#define pk_suniq pk_phead.ph_sidx.ci_uniq
#define pk_pkn pk_phead.ph_pkn
#define pk_ackn pk_phead.ph_ackn
#define pk_cdata pk_data.pk_Cdata
#define pk_idata pk_data.pk_Idata
#define pk_ldata pk_data.pk_Ldata
#define pk_receipt pk_data.pk_stsdata.pk_Receipt
#define pk_rwsize pk_data.pk_stsdata.pk_Rwsize
#define pk_rutdata pk_data.pk_Rutdata
#define pk_status pk_data.pk_Status
#define sb_ident sb_head.sb_Ident
#define sb_nshorts sb_head.sb_Nshorts
#define sb_xstat sb_union.sb_Xstat
#define ISDATOP(pkt) (((pkt)->pk_op & DATOP) != 0)
#define CONTPKT(pkt) (ISDATOP(pkt) || (pkt)->pk_op == RFCOP || \
(pkt)->pk_op == OPNOP || (pkt)->pk_op == EOFOP)
/* Here are the packet types */
#define PKNML 00 /* Normal */
#define PKLSN 01 /* Listen list packet */
/*
* This is the connection structure. These are allocated in a packet of the
* appropriate size
*/
struct connection {
struct csys_header cn_syshead; /* System dependent info */
unsigned char cn_flags; /* Random flags */
unsigned char cn_state; /* State of the connection */
chtime cn_active; /* Last time connection was active */
chaddr cn_Faddr; /* Foreign address */
chindex cn_Fidx; /* Foreign index */
chindex cn_Lidx; /* Local index */
/* transmit side state */
unsigned short cn_twsize; /* Transmit window size */
unsigned short cn_tlast; /* Last packet we sent */
unsigned short cn_trecvd; /* Last pkt receipted by him */
unsigned short cn_tacked; /* Last pkt acked by him */
struct packet *cn_thead; /* Head of list of pkts transmitted */
struct packet *cn_ttail; /* Tail of list of pkts transmitted */
#ifdef CHSTRCODE
struct packet *cn_toutput; /* Pkt being filled for output */
/* NOT a list, just one packet */
unsigned short cn_troom; /* Room left in cn_toutput packet */
/* pk_len shows current fill level */
#endif
/* receive side state */
unsigned short cn_rwsize; /* Receive window size */
unsigned short cn_rlast; /* Last pkt rcvd (in order) */
unsigned short cn_racked; /* Last pkt acked by us */
unsigned short cn_rread; /* Last pkt read by our user */
unsigned short cn_rsts; /* Max rread-racked before auto STS */
#ifdef CHSTRCODE
unsigned short cn_roffset; /* read offset in current packet */
/* which is conn->cn_rhead */
#endif
struct packet *cn_rhead; /* Head of ordered rcvd pkts */
struct packet *cn_rtail; /* Tail of ordered received packets */
struct packet *cn_routorder; /* list of out of order packets */
};
#define cn_fidx cn_Fidx.ci_idx
#define cn_faddr cn_Faddr.ch_addr
#define cn_fhost cn_Faddr.ch_host
#define cn_fsubnet cn_Faddr.ch_subnet
#define cn_lidx cn_Lidx.ci_idx
#define cn_ltidx cn_Lidx.ci_tidx
#define cn_luniq cn_Lidx.ci_uniq
/* bit values for cn_flags */
#ifdef CHSTRCODE
#define CHEOFSEEN 1 /* EOF packet received and acknowledged */
#endif
#define CHANSWER 2 /* This connection should send an ANS pkt */
/* macros for certain connection states */
#define chtfull(conn) ((conn)->cn_state == CSOPEN && \
(short)((conn)->cn_tlast - (conn)->cn_tacked) >= \
(conn)->cn_twsize)
#define chtempty(conn) ((conn)->cn_state != CSOPEN || \
(conn)->cn_tlast == (conn)->cn_tacked)
#define chrempty(conn) ((conn)->cn_rhead == NOPKT && \
(conn)->cn_state == CSOPEN)
#define NOCONN ((struct connection *)0)
#define connalloc() ((struct connection *)ch_alloc(sizeof(struct connection),0))
/*
* These are unsigned comparisons
* all the casting is necessary due to compiler flakiness with shorts etc.
* cmp_lt(a,b) is true if a < b, cmp_le(a,b) if a <= b, cmp_gt(a,b) if a > b
* and cmp_ge(a,b) if a >= b
*/
#define cmp_gt(a,b) (0100000 & (b - a))
#define cmp_ge(a,b) !(cmp_lt(a,b)
#define cmp_lt(a,b) cmp_gt(b, a)
#define cmp_le(a,b) !cmp_gt(a,b)
/* codes for error returns in various places - needs cleaning up somewhat */
#define CHERROR -1
#define CHEOF -2
#define CHNOPKT -3 /* No packets */
#define CHNOCONN -4 /* No connections */
#define CHCTIMEOUT -5 /* Time out */
#define CHTEMP -6
/*
* Network interface structure.
*
* There is one chxcvr structure for each interface connected to this host,
* all of which are defined in the file "chconf.c". The xcinfo is a union
* of structures needed for each device type's device dependent state.
* This union should be defined in "chconf.h"
* The bottom level device driver routines define arrays of these structures
* one per interface of a given type and find the structure appropriate
* to a given interface by indexing on the device number given in the
* interrupt vector. The top level gets at an chxcvr structure through
* the routing table.
* The ttime and rtime values are for timing-out hung transmitters or
* receivers. The drivers must ensure that tpkt and rpkt are only nonzero
* when there is really a packet being received or transmitted. This may
* be partly useless for dma (or other packet-atomic) interfaces.
*/
struct chxcvr {
struct packet *xc_list; /* Packets to be transmitted */
struct packet *xc_tail; /* Tail of xc_list */
struct packet *xc_tpkt; /* Packet being transmitted */
struct packet *xc_rpkt; /* Packet being received */
chtime xc_ttime; /* Time tpkt begun transmission */
chtime xc_rtime; /* Time rpkt began reception */
chaddr xc_Addr; /* Address of this interface */
unsigned *xc_devaddr; /* Device address (UNIBUS) */
int (*xc_start)(); /* Start routine for idle xmtr */
int (*xc_reset)(); /* Reset routine for interface */
struct statxcvr xc_xstat; /* Xcvr metering */
union xcinfo xc_info; /* Device dependent info */
};
#define xc_addr xc_Addr.ch_addr
#define xc_subnet xc_Addr.ch_subnet
#define xc_host xc_Addr.ch_host
#define xc_rcvd xc_xstat.sx_Rcvd
#define xc_xmtd xc_xstat.sx_Xmtd
#define xc_crcr xc_xstat.sx_Crcr
#define xc_crci xc_xstat.sx_Crci
#define xc_lost xc_xstat.sx_Lost
#define xc_leng xc_xstat.sx_Leng
#define xc_rej xc_xstat.sx_Rej
#define xc_abrt xc_xstat.sx_Abrt
#define NOXCVR ((struct chxcvr *)0)
/*
* Routing table entry structure.
* One per subnet possibly accessible from this host.
* Entries for directly connected subnets point to hardware
* transceiver structure (rt_type == CHDIRECT).
* Bridges (rt_type == CHFIXED or CHBRIDGE) have address of
* directly connected bridges.
*/
struct chroute {
union {
struct chxcvr *rt_Xcvr; /* interface to use */
chaddr rt_Addr; /* bridge address */
} rt_u;
unsigned char rt_type; /* type of access */
unsigned short rt_cost; /* cost of access path */
};
#define rt_xcvr rt_u.rt_Xcvr
#define rt_addr rt_u.rt_Addr.ch_addr
#define rt_host rt_u.rt_Addr.ch_host
#define rt_subnet rt_u.rt_Addr.ch_subnet
/* values for rt_type */
#define CHNOPATH 0 /* No path to this subnet yet (now) */
#define CHDIRECT 1 /* Either chaos cable or other hardware */
#define CHFIXED 2 /* Unvarying bridge */
#define CHBRIDGE 3 /* Bridge - known via RUT packet */
/* initial values for rt_cost depending on rt_type */
#define CHDCOST 10 /* Directly connected hardware (ala dr11) */
#define CHCCOST 16 /* Chaos cable connection (ether) */
#define CHACOST 20 /* Async or other slow link */
#define CHHCOST 512 /* "high" cost */
/* definition of globals */
#ifdef CHDEFINE
#define EXTERN
# ifdef DEBUG
int Chdebug = 0;
# endif
#else
#define EXTERN extern
# ifdef DEBUG
EXTERN int Chdebug;
# endif
#endif CHDEFINE
EXTERN int Chaos_error;
EXTERN struct connection *Chconntab[CHNCONNS]; /* connection table */
EXTERN chtime Chclock; /* clock (mod ??) */
EXTERN struct packet *Chlsnlist, /* listening connections */
*Chrfclist, /* list of unmatched rfc's */
*Chrfctail; /* tail of same list */
EXTERN struct chroute Chroutetab[CHNSUBNET]; /* subnet routing table */
EXTERN int Chhz; /* Hertz of clock */
EXTERN int Chrfcrcv; /* Flag for rfc reader */
extern short Chmyaddr; /* This ncp'c host number */
extern char Chmyname[]; /* This ncp's host name */
extern char *ch_alloc();
extern struct packet *pktstr(), *ch_rnext(), *xmitnext();
extern struct connection *allconn(), *ch_open(), *ch_listen();
/* debugging instrumentation */
#ifdef DEBUG
#define debug(a,b) if(Chdebug&(a)) b; else /* expect a ; after! */
#define DALLOC 1 /* Allocation tracing */
#define DTRANS 2 /* Transmitter tracing */
#define DCONN 4 /* Connection activity */
#define DPKT 8 /* Print packets */
#define DNOCLK 16 /* No clock timeouts */
#define DABNOR 32 /* Abnormal events */
#define DSEND 64 /* Trace each packet sent */
#else
#define debug(a,b)
#endif
#endif