1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
|
/*
* Copyright (c) 1996-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* Author: Hartmut Brandt <harti@freebsd.org>
*
* $Begemot: libunimsg/netnatm/saal/sscoppriv.h,v 1.4 2004/07/08 08:22:17 brandt Exp $
*
* Private SSCOP definitions.
*
*/
#ifdef _KERNEL
#ifdef __FreeBSD__
#include <netgraph/atm/sscop/ng_sscop_cust.h>
#endif
#else /* !_KERNEL */
#include "sscopcust.h"
#endif
/* Argh. BSDi */
#ifndef _BYTE_ORDER
#ifndef BYTE_ORDER
#error "_BYTE_ORDER not defined"
#endif
#define _BYTE_ORDER BYTE_ORDER
#define _LITTLE_ENDIAN LITTLE_ENDIAN
#define _BIG_ENDIAN BIG_ENDIAN
#endif
/*
* PDU trailer
*/
union pdu {
u_int sscop_null;
struct {
#if _BYTE_ORDER == _BIG_ENDIAN
u_int pl : 2; /* pad length */
u_int : 1; /* reserved field */
u_int s : 1; /* source */
u_int type : 4; /* PDU type */
u_int ns : 24; /* sequence number */
#else
u_int ns : 24; /* sequence number */
u_int type : 4; /* PDU type */
u_int s : 1; /* source */
u_int : 1; /* reserved field */
u_int pl : 2; /* pad length */
#endif
} ss;
};
#define sscop_pl ss.pl
#define sscop_s ss.s
#define sscop_type ss.type
#define sscop_ns ss.ns
/*
* seqno list entry format
*/
union seqno {
u_int sscop_null;
struct {
#if _BYTE_ORDER == _BIG_ENDIAN
u_int : 8; /* pad */
u_int n : 24; /* seqno */
#else
u_int n : 24; /* seqno */
u_int : 8; /* pad */
#endif
} ss;
};
#define sscop_n ss.n
/*
* Begin pdu
*/
union bgn {
u_int sscop_null;
struct {
#if _BYTE_ORDER == _BIG_ENDIAN
u_int : 24; /* reserved */
u_int bgns : 8; /* VT_MR */
#else
u_int bgns : 8; /* VT_MR */
u_int : 24; /* reserved */
#endif
} ss;
};
#define sscop_bgns ss.bgns
/*
* pdu types
*/
enum pdu_type {
PDU_BGN = 0x1, /* request initialization */
PDU_BGAK = 0x2, /* request acknowledgement */
PDU_END = 0x3, /* disconnect command */
PDU_ENDAK = 0x4, /* disconnect acknowledgement */
PDU_RS = 0x5, /* resynchronisation command */
PDU_RSAK = 0x6, /* resynchronisation acknowledgement */
PDU_BGREJ = 0x7, /* connection reject */
PDU_SD = 0x8, /* sequenced connection-mode data */
PDU_ER = 0x9, /* recovery command */
PDU_POLL = 0xa, /* xmit state info with req. for recv state */
PDU_STAT = 0xb, /* solicited receiver state info */
PDU_USTAT = 0xc, /* unsolicited receiver state info */
PDU_UD = 0xd, /* unumbered user data */
PDU_MD = 0xe, /* unumbered management data */
PDU_ERAK = 0xf, /* recovery acknowledgement */
};
/*
* These are all signals, that are used by SSCOP. Don't change the order or
* number without also changing the associated tables.
*/
enum sscop_sigtype {
/* received PDU's */
SIG_BGN, /* request initialization */
SIG_BGAK, /* request acknowledgement */
SIG_END, /* disconnect command */
SIG_ENDAK, /* disconnect acknowledgement */
SIG_RS, /* resynchronisation command */
SIG_RSAK, /* resynchronisation acknowledgement */
SIG_BGREJ, /* connection reject */
SIG_SD, /* sequenced connection-mode data */
SIG_ER, /* recovery command */
SIG_POLL, /* xmitter state info with req for recv state */
SIG_STAT, /* solicited receiver state info */
SIG_USTAT, /* unsolicited receiver state info */
SIG_UD, /* unumbered user data */
SIG_MD, /* unumbered management data */
SIG_ERAK, /* recovery acknoledgement */
/* timer expiry */
SIG_T_CC, /* CC timer */
SIG_T_POLL, /* POLL timer */
SIG_T_KA, /* KEEP ALIVE timer */
SIG_T_NR, /* NO RESPONSE timer */
SIG_T_IDLE, /* IDLE timer */
/* user originated signals */
SIG_PDU_Q, /* PDU enqueued pseudosignal */
SIG_USER_DATA, /* user data request */
SIG_ESTAB_REQ, /* establish connection request */
SIG_ESTAB_RESP, /* establish connection response */
SIG_RELEASE_REQ, /* release connection request */
SIG_RECOVER, /* automatic recover response */
SIG_SYNC_REQ, /* resynchronisation request */
SIG_SYNC_RESP, /* resynchronisation response */
SIG_UDATA, /* UDATA request */
SIG_MDATA, /* MDATA request */
SIG_UPDU_Q, /* UDATA PDU enqueued pseudosignal */
SIG_MPDU_Q, /* MDATA PDU enqueued pseudosignal */
SIG_RETRIEVE, /* RETRIEVE */
/* number of signals */
SIG_NUM
};
/*
* This is a message as contained in a sscop message queue. It holds a pointer
* to the real message.
*/
struct sscop_msg {
sscop_msgq_link_t link;
u_int seqno; /* seq no */
u_int poll_seqno; /* poll seqno (for messages in xmit buffer) */
u_int rexmit; /* in retransmission queue? */
struct SSCOP_MBUF_T *m; /* the message */
};
/*
* This structure is used to hold signals in the signal queue
*/
struct sscop_sig {
sscop_sigq_link_t link; /* next signal */
enum sscop_sigtype sig; /* THE signal */
struct sscop_msg *msg; /* signal argument (message) */
};
/*
* This structure holds the entire sscop state
*/
struct sscop {
enum sscop_state state; /* current state */
const struct sscop_funcs *funcs;
/* send state */
u_int vt_s; /* seqno for next pdu first time transmitted */
u_int vt_ps; /* current poll seqno */
u_int vt_a; /* next expected in-sequence sd pdu */
u_int vt_pa; /* poll seqno of next stat pdu */
u_int vt_ms; /* maximum allowed send sd seqno */
u_int vt_pd; /* poll data state */
u_int vt_cc; /* connection control state */
u_int vt_sq; /* transmitter connection sequence */
/* receive state */
u_int vr_r; /* receive state */
u_int vr_h; /* highes expected state */
u_int vr_mr; /* maximum acceptable */
u_int vr_sq; /* receiver connection state */
/* timers */
sscop_timer_t t_cc; /* timer_CC */
sscop_timer_t t_nr; /* timer_NO_RESPONSE */
sscop_timer_t t_ka; /* timer KEEP_ALIVE */
sscop_timer_t t_poll; /* timer_POLL */
sscop_timer_t t_idle; /* idle timer */
/* maximum values */
u_int maxj; /* maximum uu-info */
u_int maxk; /* maximum info */
u_int maxcc; /* maximum number of bgn, end, er and rs */
u_int maxpd; /* maximum value of vt_pd */
u_int maxstat; /* maximum length of list */
u_int timercc; /* connection control timer */
u_int timerka; /* keep alive timer */
u_int timernr; /* no response timer */
u_int timerpoll; /* polling */
u_int timeridle; /* idle timer */
u_int robustness; /* atmf/97-0216 robustness enhancement */
u_int poll_after_rex; /* optional POLL after re-transmission */
u_int mr; /* initial window */
/*
* buffers and queues.
* All expect the xq hold SD PDUs.
*/
sscop_msgq_head_t xq; /* xmit queue (input from user before xmit) */
sscop_msgq_head_t uxq; /* UD xmit queue */
sscop_msgq_head_t mxq; /* MD xmit queue */
sscop_msgq_head_t xbuf; /* transmission buffer (SD PDUs transmitted) */
int rxq; /* number of PDUs in retransmission queue */
sscop_msgq_head_t rbuf; /* receive buffer (SD PDUs) */
int last_end_src; /* source field from last xmitted end pdu */
int clear_buffers; /* flag */
int credit; /* send window not closed */
u_int ll_busy; /* lower layer busy */
u_int rs_mr; /* N(MR) in last RS PDU */
u_int rs_sq; /* N(SQ) in last RS PDU */
struct SSCOP_MBUF_T *uu_bgn; /* last UU data */
struct SSCOP_MBUF_T *uu_bgak; /* ... */
struct SSCOP_MBUF_T *uu_bgrej; /* ... */
struct SSCOP_MBUF_T *uu_end; /* ... */
struct SSCOP_MBUF_T *uu_rs; /* ... */
/* signal queues */
sscop_sigq_head_t sigs; /* saved signals */
sscop_sigq_head_t saved_sigs; /* saved signals */
int in_sig; /* in signal handler */
/* debugging */
u_int debug;
/* AA interface */
void *aarg;
};
/*
* Default values for SSCOP
*/
enum {
MAXK = 4096,
MAXMAXK = 65528,
MAXJ = 4096,
MAXMAXJ = 65524,
MAXCC = 4,
MAXSTAT = 67,
MAXPD = 25,
MAXMR = 128, /* ??? */
TIMERCC = 1000,
TIMERKA = 2000,
TIMERNR = 7000,
TIMERPOLL = 750,
TIMERIDLE = 15000,
};
/*
* Sequence number arithmetic
*/
#define SEQNO_DIFF(A,B) (((A) < (B)) ? ((A) + (1<<24) - (B)) : ((A) - (B)))
/*
* Debugging
*/
#ifdef SSCOP_DEBUG
#define VERBOSE(S,M,F) if ((S)->debug & (M)) (S)->funcs->verbose F
#define VERBERR(S,M,F) if ((S)->debug & (M)) (S)->funcs->verbose F
#define ISVERBOSE(S,M) ((S)->debug & (M))
#else
#define VERBOSE(S,M,F)
#define VERBERR(S,M,F)
#define ISVERBOSE(S,M) (0)
#endif
|