summaryrefslogtreecommitdiffstats
path: root/3rdparty/openpgm-svn-r1085/pgm/include/pgm/packet.h
blob: b1bb639d2e12842dfd0be2e4678f5a2a498482dc (plain) (blame)
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
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
/* vim:ts=8:sts=4:sw=4:noai:noexpandtab
 * 
 * PGM packet formats, RFC 3208.
 *
 * Copyright (c) 2006 Miru Limited.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __PGM_PACKET_H__
#define __PGM_PACKET_H__

#ifndef _WIN32
#	include <sys/socket.h>
#	include <netinet/in.h>
#	include <netinet/ip.h>
#endif
#include <pgm/types.h>

PGM_BEGIN_DECLS

/* protocol number assigned by IANA */
#ifndef IPPROTO_PGM
#	define IPPROTO_PGM 		    	113
#endif

/* read from /etc/protocols if available */
extern int pgm_ipproto_pgm;


/* address family indicator, rfc 1700 (ADDRESS FAMILY NUMBERS) */
#ifndef AFI_IP
#	define AFI_IP	    1	    /* IP (IP version 4) */
#	define AFI_IP6	    2	    /* IP6 (IP version 6) */
#endif

/* UDP ports for UDP encapsulation, as per IBM WebSphere MQ */
#define DEFAULT_UDP_ENCAP_UCAST_PORT	3055
#define DEFAULT_UDP_ENCAP_MCAST_PORT	3056

/* PGM default ports */
#define DEFAULT_DATA_DESTINATION_PORT	7500
#define DEFAULT_DATA_SOURCE_PORT	0	/* random */

/* DoS limitation to protocol (MS08-036, KB950762) */
#ifndef PGM_MAX_APDU
#	define PGM_MAX_APDU			UINT16_MAX
#endif

/* Cisco default: 24 (max 8200), Juniper & H3C default: 16, SmartPGM: 64 */
#ifndef PGM_MAX_FRAGMENTS
#	define PGM_MAX_FRAGMENTS		16
#endif


enum pgm_type_e {
	PGM_SPM		= 0x00,	/* 8.1: source path message */
	PGM_POLL	= 0x01,	/* 14.7.1: poll request */
	PGM_POLR	= 0x02,	/* 14.7.2: poll response */
	PGM_ODATA	= 0x04,	/* 8.2: original data */
	PGM_RDATA	= 0x05,	/* 8.2: repair data */
	PGM_NAK		= 0x08,	/* 8.3: NAK or negative acknowledgement */
	PGM_NNAK	= 0x09,	/* 8.3: N-NAK or null negative acknowledgement */
	PGM_NCF		= 0x0a,	/* 8.3: NCF or NAK confirmation */
	PGM_SPMR	= 0x0c,	/* 13.6: SPM request */
	PGM_ACK		= 0x0d,	/* PGMCC: congestion control ACK */
	PGM_MAX		= 0xff
};

#define PGM_OPT_LENGTH		    0x00	/* options length */
#define PGM_OPT_FRAGMENT	    0x01	/* fragmentation */
#define PGM_OPT_NAK_LIST	    0x02	/* list of nak entries */
#define PGM_OPT_JOIN		    0x03	/* late joining */
#define PGM_OPT_REDIRECT	    0x07	/* redirect */
#define PGM_OPT_SYN		    0x0d	/* synchronisation */
#define PGM_OPT_FIN		    0x0e	/* session end */
#define PGM_OPT_RST		    0x0f	/* session reset */

#define PGM_OPT_PARITY_PRM	    0x08	/* forward error correction parameters */
#define PGM_OPT_PARITY_GRP	    0x09	/*   group number */
#define PGM_OPT_CURR_TGSIZE	    0x0a	/*   group size */

#define PGM_OPT_CR		    0x10	/* congestion report */
#define PGM_OPT_CRQST		    0x11	/* congestion report request */

#define PGM_OPT_PGMCC_DATA	    0x12
#define PGM_OPT_PGMCC_FEEDBACK	    0x13

#define PGM_OPT_NAK_BO_IVL	    0x04	/* nak back-off interval */
#define PGM_OPT_NAK_BO_RNG	    0x05	/* nak back-off range */
#define PGM_OPT_NBR_UNREACH	    0x0b	/* neighbour unreachable */
#define PGM_OPT_PATH_NLA	    0x0c	/* path nla */

#define PGM_OPT_INVALID		    0x7f	/* option invalidated */

/* byte alignment for packet memory maps */
#if defined( __GNUC__ ) && !defined( sun )
#	pragma pack(push)
#endif
#pragma pack(1)

/* 8. PGM header */
struct pgm_header {
	uint16_t	pgm_sport;		/* source port: tsi::sport or UDP port depending on direction */
	uint16_t	pgm_dport;		/* destination port */
	uint8_t		pgm_type;		/* version / packet type */
	uint8_t		pgm_options;		/* options */
#define PGM_OPT_PARITY		0x80	/* parity packet */
#define PGM_OPT_VAR_PKTLEN	0x40	/* + variable sized packets */
#define PGM_OPT_NETWORK		0x02    /* network-significant: must be interpreted by network elements */
#define PGM_OPT_PRESENT		0x01	/* option extension are present */
	uint16_t	pgm_checksum;		/* checksum */
	uint8_t		pgm_gsi[6];		/* global source id */
	uint16_t	pgm_tsdu_length;	/* tsdu length */
				/* tpdu length = th length (header + options) + tsdu length */
};

/* 8.1.  Source Path Messages (SPM) */
struct pgm_spm {
	uint32_t	spm_sqn;		/* spm sequence number */
	uint32_t	spm_trail;		/* trailing edge sequence number */
	uint32_t	spm_lead;		/* leading edge sequence number */
	uint16_t	spm_nla_afi;		/* nla afi */
	uint16_t	spm_reserved;		/* reserved */
	struct in_addr	spm_nla;		/* path nla */
	/* ... option extensions */
};

struct pgm_spm6 {
	uint32_t	spm6_sqn;		/* spm sequence number */
	uint32_t	spm6_trail;		/* trailing edge sequence number */
	uint32_t	spm6_lead;		/* leading edge sequence number */
	uint16_t	spm6_nla_afi;		/* nla afi */
	uint16_t	spm6_reserved;		/* reserved */
	struct in6_addr spm6_nla;		/* path nla */
	/* ... option extensions */
};

/* 8.2.  Data Packet */
struct pgm_data {
	uint32_t	data_sqn;		/* data packet sequence number */
	uint32_t	data_trail;		/* trailing edge sequence number */
	/* ... option extensions */
	/* ... data */
};

/* 8.3.  Negative Acknowledgments and Confirmations (NAK, N-NAK, & NCF) */
struct pgm_nak {
	uint32_t	nak_sqn;		/* requested sequence number */
	uint16_t	nak_src_nla_afi;	/* nla afi */
	uint16_t	nak_reserved;		/* reserved */
	struct in_addr	nak_src_nla;		/* source nla */
	uint16_t	nak_grp_nla_afi;	/* nla afi */
	uint16_t	nak_reserved2;		/* reserved */
	struct in_addr	nak_grp_nla;		/* multicast group nla */
	/* ... option extension */
};

struct pgm_nak6 {
	uint32_t	nak6_sqn;		/* requested sequence number */
	uint16_t	nak6_src_nla_afi;	/* nla afi */
	uint16_t	nak6_reserved;		/* reserved */
	struct in6_addr nak6_src_nla;	/* source nla */
	uint16_t	nak6_grp_nla_afi;	/* nla afi */
	uint16_t	nak6_reserved2;		/* reserved */
	struct in6_addr nak6_grp_nla;	/* multicast group nla */
	/* ... option extension */
};

/* 9.  Option header (max 16 per packet) */
struct pgm_opt_header {
	uint8_t		opt_type;		/* option type */
#define PGM_OPT_MASK		0x7f
#define PGM_OPT_END		0x80	/* end of options flag */
	uint8_t		opt_length;		/* option length */
	uint8_t		opt_reserved;
#define PGM_OP_ENCODED		0x8	/* F-bit */
#define PGM_OPX_MASK		0x3
#define PGM_OPX_IGNORE		0x0	/* extensibility bits */
#define PGM_OPX_INVALIDATE	0x1
#define PGM_OPX_DISCARD		0x2
#define PGM_OP_ENCODED_NULL	0x80	/* U-bit */
};

/* 9.1.  Option extension length - OPT_LENGTH */
struct pgm_opt_length {
	uint8_t		opt_type;		/* include header as total length overwrites reserved/OPX bits */
	uint8_t		opt_length;
	uint16_t	opt_total_length;	/* total length of all options */
};

/* 9.2.  Option fragment - OPT_FRAGMENT */
struct pgm_opt_fragment {
	uint8_t		opt_reserved;		/* reserved */
	uint32_t	opt_sqn;		/* first sequence number */
	uint32_t	opt_frag_off;		/* offset */
	uint32_t	opt_frag_len;		/* length */
};

/* 9.3.5.  Option NAK List - OPT_NAK_LIST
 *
 * GNU C allows opt_sqn[0], ISO C89 requireqs opt_sqn[1], ISO C99 permits opt_sqn[]
 */
struct pgm_opt_nak_list {
	uint8_t		opt_reserved;		/* reserved */
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
	uint32_t	opt_sqn[];		/* requested sequence number [62] */
#elif defined(__cplusplus)
	uint32_t	opt_sqn[1];
#else
	uint32_t	opt_sqn[0];
#endif
};

/* 9.4.2.  Option Join - OPT_JOIN */
struct pgm_opt_join {
	uint8_t		opt_reserved;		/* reserved */
	uint32_t	opt_join_min;		/* minimum sequence number */
};

/* 9.5.5.  Option Redirect - OPT_REDIRECT */
struct pgm_opt_redirect {
	uint8_t		opt_reserved;		/* reserved */
	uint16_t	opt_nla_afi;		/* nla afi */
	uint16_t	opt_reserved2;		/* reserved */
	struct in_addr	opt_nla;		/* dlr nla */
};

struct pgm_opt6_redirect {
	uint8_t		opt6_reserved;		/* reserved */
	uint16_t	opt6_nla_afi;		/* nla afi */
	uint16_t	opt6_reserved2;		/* reserved */
	struct in6_addr opt6_nla;		/* dlr nla */
};

/* 9.6.2.  Option Sources - OPT_SYN */
struct pgm_opt_syn {
	uint8_t		opt_reserved;		/* reserved */
};

/* 9.7.4.  Option End Session - OPT_FIN */
struct pgm_opt_fin {
	uint8_t		opt_reserved;		/* reserved */
};

/* 9.8.4.  Option Reset - OPT_RST */
struct pgm_opt_rst {
	uint8_t		opt_reserved;		/* reserved */
};


/*
 * Forward Error Correction - FEC
 */

/* 11.8.1.  Option Parity - OPT_PARITY_PRM */
struct pgm_opt_parity_prm {
	uint8_t		opt_reserved;		/* reserved */
#define PGM_PARITY_PRM_MASK 0x3
#define PGM_PARITY_PRM_PRO  0x1		/* source provides pro-active parity packets */
#define PGM_PARITY_PRM_OND  0x2		/*                 on-demand parity packets */
	uint32_t	parity_prm_tgs;		/* transmission group size */
};

/* 11.8.2.  Option Parity Group - OPT_PARITY_GRP */
struct pgm_opt_parity_grp {
	uint8_t		opt_reserved;		/* reserved */
	uint32_t	prm_group;		/* parity group number */
};

/* 11.8.3.  Option Current Transmission Group Size - OPT_CURR_TGSIZE */
struct pgm_opt_curr_tgsize {
	uint8_t		opt_reserved;		/* reserved */
	uint32_t	prm_atgsize;		/* actual transmission group size */
};

/*
 * Congestion Control
 */

/* 12.7.1.  Option Congestion Report - OPT_CR */
struct pgm_opt_cr {
	uint8_t		opt_reserved;		/* reserved */
#define PGM_OPT_CR_NEL		0x0	/* OPT_CR_NE_WL report */
#define PGM_OPT_CR_NEP		0x1	/* OPT_CR_NE_WP report */
#define PGM_OPT_CR_RXP		0x2	/* OPT_CR_RX_WP report */
	uint32_t	opt_cr_lead;		/* congestion report reference sqn */
	uint16_t	opt_cr_ne_wl;		/* ne worst link */
	uint16_t	opt_cr_ne_wp;		/* ne worst path */
	uint16_t	opt_cr_rx_wp;		/* rcvr worst path */
	uint16_t	opt_reserved2;		/* reserved */
	uint16_t	opt_nla_afi;		/* nla afi */
	uint16_t	opt_reserved3;		/* reserved */
	uint32_t	opt_cr_rcvr;		/* worst receivers nla */
};

/* 12.7.2.  Option Congestion Report Request - OPT_CRQST */
struct pgm_opt_crqst {
	uint8_t		opt_reserved;		/* reserved */
#define PGM_OPT_CRQST_NEL	0x0	/* request OPT_CR_NE_WL report */
#define PGM_OPT_CRQST_NEP	0x1	/* request OPT_CR_NE_WP report */
#define PGM_OPT_CRQST_RXP	0x2	/* request OPT_CR_RX_WP report */
};

/* PGMCC.  ACK Packet */
struct pgm_ack {
	uint32_t	ack_rx_max;		/* RX_MAX */
	uint32_t	ack_bitmap;		/* received packets */
	/* ... option extensions */
};

/* PGMCC  Options */
struct pgm_opt_pgmcc_data {
	uint8_t		opt_reserved;		/* reserved */
	uint32_t	opt_tstamp;		/* timestamp */
	uint16_t	opt_nla_afi;		/* nla afi */
	uint16_t	opt_reserved2;		/* reserved */
	struct in_addr	opt_nla;		/* ACKER nla */
};

struct pgm_opt6_pgmcc_data {
	uint8_t		opt6_reserved;		/* reserved */
	uint32_t	opt6_tstamp;		/* timestamp */
	uint16_t	opt6_nla_afi;		/* nla afi */
	uint16_t	opt6_reserved2;		/* reserved */
	struct in6_addr	opt6_nla;		/* ACKER nla */
};

struct pgm_opt_pgmcc_feedback {
	uint8_t		opt_reserved;		/* reserved */
	uint32_t	opt_tstamp;		/* timestamp */
	uint16_t	opt_nla_afi;		/* nla afi */
	uint16_t	opt_loss_rate;		/* loss rate */
	struct in_addr	opt_nla;		/* ACKER nla */
};

struct pgm_opt6_pgmcc_feedback {
	uint8_t		opt6_reserved;		/* reserved */
	uint32_t	opt6_tstamp;		/* timestamp */
	uint16_t	opt6_nla_afi;		/* nla afi */
	uint16_t	opt6_loss_rate;		/* loss rate */
	struct in6_addr	opt6_nla;		/* ACKER nla */
};


/*
 * SPM Requests
 */

/* 13.6.  SPM Requests */
#if 0
struct pgm_spmr {
    /* ... option extensions */
};
#endif


/*
 * Poll Mechanism
 */

/* 14.7.1.  Poll Request */
struct pgm_poll {
	uint32_t	poll_sqn;		/* poll sequence number */
	uint16_t	poll_round;		/* poll round */
	uint16_t	poll_s_type;		/* poll sub-type */
#define PGM_POLL_GENERAL	0x0	/* general poll  */
#define PGM_POLL_DLR		0x1	/* DLR poll */
	uint16_t	poll_nla_afi;		/* nla afi */
	uint16_t	poll_reserved;		/* reserved */
	struct in_addr	poll_nla;		/* path nla */
	uint32_t	poll_bo_ivl;		/* poll back-off interval */
	char		poll_rand[4];		/* random string */
	uint32_t	poll_mask;		/* matching bit-mask */
    /* ... option extensions */
};

struct pgm_poll6 {
	uint32_t	poll6_sqn;		/* poll sequence number */
	uint16_t	poll6_round;		/* poll round */
	uint16_t	poll6_s_type;		/* poll sub-type */
	uint16_t	poll6_nla_afi;		/* nla afi */
	uint16_t	poll6_reserved;		/* reserved */
	struct in6_addr poll6_nla;		/* path nla */
	uint32_t	poll6_bo_ivl;		/* poll back-off interval */
	char		poll6_rand[4];		/* random string */
	uint32_t	poll6_mask;		/* matching bit-mask */
    /* ... option extensions */
};

/* 14.7.2.  Poll Response */
struct pgm_polr {
	uint32_t	polr_sqn;		/* polr sequence number */
	uint16_t	polr_round;		/* polr round */
	uint16_t	polr_reserved;		/* reserved */
    /* ... option extensions */
};


/*
 * Implosion Prevention
 */

/* 15.4.1.  Option NAK Back-Off Interval - OPT_NAK_BO_IVL */
struct pgm_opt_nak_bo_ivl {
	uint8_t		opt_reserved;		/* reserved */
	uint32_t	opt_nak_bo_ivl;		/* nak back-off interval */
	uint32_t	opt_nak_bo_ivl_sqn;	/* nak back-off interval sqn */
};

/* 15.4.2.  Option NAK Back-Off Range - OPT_NAK_BO_RNG */
struct pgm_opt_nak_bo_rng {
	uint8_t		opt_reserved;		/* reserved */
	uint32_t	opt_nak_max_bo_ivl;	/* maximum nak back-off interval */
	uint32_t	opt_nak_min_bo_ivl;	/* minimum nak back-off interval */
};

/* 15.4.3.  Option Neighbour Unreachable - OPT_NBR_UNREACH */
struct pgm_opt_nbr_unreach {
	uint8_t		opt_reserved;		/* reserved */
};

/* 15.4.4.  Option Path - OPT_PATH_NLA */
struct pgm_opt_path_nla {
	uint8_t		opt_reserved;		/* reserved */
	struct in_addr	opt_path_nla;		/* path nla */
};

struct pgm_opt6_path_nla {
	uint8_t		opt6_reserved;		/* reserved */
	struct in6_addr opt6_path_nla;		/* path nla */
};


#if defined( __GNUC__ ) && !defined( sun )
#	pragma pack(pop)
#else
#	pragma pack()
#endif

#define PGM_IS_UPSTREAM(t) \
	((t) == PGM_NAK 	/* unicast */			\
	 || (t) == PGM_NNAK	/* unicast */			\
	 || (t) == PGM_SPMR	/* multicast + unicast */	\
	 || (t) == PGM_POLR	/* unicast */			\
	 || (t) == PGM_ACK)	/* unicast */

#define PGM_IS_PEER(t) \
	((t) == PGM_SPMR)	/* multicast */

#define PGM_IS_DOWNSTREAM(t) \
	((t) == PGM_SPM		/* all types are multicast */	\
	 || (t) == PGM_ODATA					\
	 || (t) == PGM_RDATA					\
	 || (t) == PGM_POLL					\
	 || (t) == PGM_NCF)

PGM_END_DECLS

#endif /* __PGM_PACKET_H__ */