diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/net/sctp/sm.h |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/net/sctp/sm.h')
-rw-r--r-- | include/net/sctp/sm.h | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h new file mode 100644 index 000000000000..5576db56324d --- /dev/null +++ b/include/net/sctp/sm.h | |||
@@ -0,0 +1,442 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | ||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | ||
5 | * Copyright (c) 2001 Intel Corp. | ||
6 | * | ||
7 | * This file is part of the SCTP kernel reference Implementation | ||
8 | * | ||
9 | * These are definitions needed by the state machine. | ||
10 | * | ||
11 | * The SCTP reference implementation is free software; | ||
12 | * you can redistribute it and/or modify it under the terms of | ||
13 | * the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2, or (at your option) | ||
15 | * any later version. | ||
16 | * | ||
17 | * The SCTP reference implementation is distributed in the hope that it | ||
18 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
19 | * ************************ | ||
20 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
21 | * See the GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with GNU CC; see the file COPYING. If not, write to | ||
25 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
26 | * Boston, MA 02111-1307, USA. | ||
27 | * | ||
28 | * Please send any bug reports or fixes you make to the | ||
29 | * email addresses: | ||
30 | * lksctp developers <lksctp-developers@lists.sourceforge.net> | ||
31 | * | ||
32 | * Or submit a bug report through the following website: | ||
33 | * http://www.sf.net/projects/lksctp | ||
34 | * | ||
35 | * Written or modified by: | ||
36 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
37 | * Karl Knutson <karl@athena.chicago.il.us> | ||
38 | * Xingang Guo <xingang.guo@intel.com> | ||
39 | * Jon Grimm <jgrimm@us.ibm.com> | ||
40 | * Dajiang Zhang <dajiang.zhang@nokia.com> | ||
41 | * Sridhar Samudrala <sri@us.ibm.com> | ||
42 | * Daisy Chang <daisyc@us.ibm.com> | ||
43 | * Ardelle Fan <ardelle.fan@intel.com> | ||
44 | * Kevin Gao <kevin.gao@intel.com> | ||
45 | * | ||
46 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
47 | * be incorporated into the next SCTP release. | ||
48 | */ | ||
49 | |||
50 | #include <linux/types.h> | ||
51 | #include <linux/compiler.h> | ||
52 | #include <linux/slab.h> | ||
53 | #include <linux/in.h> | ||
54 | #include <net/sctp/command.h> | ||
55 | #include <net/sctp/sctp.h> | ||
56 | |||
57 | #ifndef __sctp_sm_h__ | ||
58 | #define __sctp_sm_h__ | ||
59 | |||
60 | /* | ||
61 | * Possible values for the disposition are: | ||
62 | */ | ||
63 | typedef enum { | ||
64 | SCTP_DISPOSITION_DISCARD, /* No further processing. */ | ||
65 | SCTP_DISPOSITION_CONSUME, /* Process return values normally. */ | ||
66 | SCTP_DISPOSITION_NOMEM, /* We ran out of memory--recover. */ | ||
67 | SCTP_DISPOSITION_DELETE_TCB, /* Close the association. */ | ||
68 | SCTP_DISPOSITION_ABORT, /* Close the association NOW. */ | ||
69 | SCTP_DISPOSITION_VIOLATION, /* The peer is misbehaving. */ | ||
70 | SCTP_DISPOSITION_NOT_IMPL, /* This entry is not implemented. */ | ||
71 | SCTP_DISPOSITION_ERROR, /* This is plain old user error. */ | ||
72 | SCTP_DISPOSITION_BUG, /* This is a bug. */ | ||
73 | } sctp_disposition_t; | ||
74 | |||
75 | typedef struct { | ||
76 | int name; | ||
77 | int action; | ||
78 | } sctp_sm_command_t; | ||
79 | |||
80 | typedef sctp_disposition_t (sctp_state_fn_t) (const struct sctp_endpoint *, | ||
81 | const struct sctp_association *, | ||
82 | const sctp_subtype_t type, | ||
83 | void *arg, | ||
84 | sctp_cmd_seq_t *); | ||
85 | typedef void (sctp_timer_event_t) (unsigned long); | ||
86 | typedef struct { | ||
87 | sctp_state_fn_t *fn; | ||
88 | const char *name; | ||
89 | } sctp_sm_table_entry_t; | ||
90 | |||
91 | /* A naming convention of "sctp_sf_xxx" applies to all the state functions | ||
92 | * currently in use. | ||
93 | */ | ||
94 | |||
95 | /* Prototypes for generic state functions. */ | ||
96 | sctp_state_fn_t sctp_sf_not_impl; | ||
97 | sctp_state_fn_t sctp_sf_bug; | ||
98 | |||
99 | /* Prototypes for gener timer state functions. */ | ||
100 | sctp_state_fn_t sctp_sf_timer_ignore; | ||
101 | |||
102 | /* Prototypes for chunk state functions. */ | ||
103 | sctp_state_fn_t sctp_sf_do_9_1_abort; | ||
104 | sctp_state_fn_t sctp_sf_cookie_wait_abort; | ||
105 | sctp_state_fn_t sctp_sf_cookie_echoed_abort; | ||
106 | sctp_state_fn_t sctp_sf_shutdown_pending_abort; | ||
107 | sctp_state_fn_t sctp_sf_shutdown_sent_abort; | ||
108 | sctp_state_fn_t sctp_sf_shutdown_ack_sent_abort; | ||
109 | sctp_state_fn_t sctp_sf_do_5_1B_init; | ||
110 | sctp_state_fn_t sctp_sf_do_5_1C_ack; | ||
111 | sctp_state_fn_t sctp_sf_do_5_1D_ce; | ||
112 | sctp_state_fn_t sctp_sf_do_5_1E_ca; | ||
113 | sctp_state_fn_t sctp_sf_do_4_C; | ||
114 | sctp_state_fn_t sctp_sf_eat_data_6_2; | ||
115 | sctp_state_fn_t sctp_sf_eat_data_fast_4_4; | ||
116 | sctp_state_fn_t sctp_sf_eat_sack_6_2; | ||
117 | sctp_state_fn_t sctp_sf_tabort_8_4_8; | ||
118 | sctp_state_fn_t sctp_sf_operr_notify; | ||
119 | sctp_state_fn_t sctp_sf_t1_timer_expire; | ||
120 | sctp_state_fn_t sctp_sf_t2_timer_expire; | ||
121 | sctp_state_fn_t sctp_sf_t4_timer_expire; | ||
122 | sctp_state_fn_t sctp_sf_t5_timer_expire; | ||
123 | sctp_state_fn_t sctp_sf_sendbeat_8_3; | ||
124 | sctp_state_fn_t sctp_sf_beat_8_3; | ||
125 | sctp_state_fn_t sctp_sf_backbeat_8_3; | ||
126 | sctp_state_fn_t sctp_sf_do_9_2_final; | ||
127 | sctp_state_fn_t sctp_sf_do_9_2_shutdown; | ||
128 | sctp_state_fn_t sctp_sf_do_ecn_cwr; | ||
129 | sctp_state_fn_t sctp_sf_do_ecne; | ||
130 | sctp_state_fn_t sctp_sf_ootb; | ||
131 | sctp_state_fn_t sctp_sf_pdiscard; | ||
132 | sctp_state_fn_t sctp_sf_violation; | ||
133 | sctp_state_fn_t sctp_sf_violation_chunklen; | ||
134 | sctp_state_fn_t sctp_sf_discard_chunk; | ||
135 | sctp_state_fn_t sctp_sf_do_5_2_1_siminit; | ||
136 | sctp_state_fn_t sctp_sf_do_5_2_2_dupinit; | ||
137 | sctp_state_fn_t sctp_sf_do_5_2_4_dupcook; | ||
138 | sctp_state_fn_t sctp_sf_unk_chunk; | ||
139 | sctp_state_fn_t sctp_sf_do_8_5_1_E_sa; | ||
140 | sctp_state_fn_t sctp_sf_cookie_echoed_err; | ||
141 | sctp_state_fn_t sctp_sf_do_asconf; | ||
142 | sctp_state_fn_t sctp_sf_do_asconf_ack; | ||
143 | sctp_state_fn_t sctp_sf_do_9_2_reshutack; | ||
144 | sctp_state_fn_t sctp_sf_eat_fwd_tsn; | ||
145 | sctp_state_fn_t sctp_sf_eat_fwd_tsn_fast; | ||
146 | |||
147 | /* Prototypes for primitive event state functions. */ | ||
148 | sctp_state_fn_t sctp_sf_do_prm_asoc; | ||
149 | sctp_state_fn_t sctp_sf_do_prm_send; | ||
150 | sctp_state_fn_t sctp_sf_do_9_2_prm_shutdown; | ||
151 | sctp_state_fn_t sctp_sf_cookie_wait_prm_shutdown; | ||
152 | sctp_state_fn_t sctp_sf_cookie_echoed_prm_shutdown; | ||
153 | sctp_state_fn_t sctp_sf_do_9_1_prm_abort; | ||
154 | sctp_state_fn_t sctp_sf_cookie_wait_prm_abort; | ||
155 | sctp_state_fn_t sctp_sf_cookie_echoed_prm_abort; | ||
156 | sctp_state_fn_t sctp_sf_shutdown_pending_prm_abort; | ||
157 | sctp_state_fn_t sctp_sf_shutdown_sent_prm_abort; | ||
158 | sctp_state_fn_t sctp_sf_shutdown_ack_sent_prm_abort; | ||
159 | sctp_state_fn_t sctp_sf_error_closed; | ||
160 | sctp_state_fn_t sctp_sf_error_shutdown; | ||
161 | sctp_state_fn_t sctp_sf_ignore_primitive; | ||
162 | sctp_state_fn_t sctp_sf_do_prm_requestheartbeat; | ||
163 | sctp_state_fn_t sctp_sf_do_prm_asconf; | ||
164 | |||
165 | /* Prototypes for other event state functions. */ | ||
166 | sctp_state_fn_t sctp_sf_do_9_2_start_shutdown; | ||
167 | sctp_state_fn_t sctp_sf_do_9_2_shutdown_ack; | ||
168 | sctp_state_fn_t sctp_sf_ignore_other; | ||
169 | sctp_state_fn_t sctp_sf_cookie_wait_icmp_abort; | ||
170 | |||
171 | /* Prototypes for timeout event state functions. */ | ||
172 | sctp_state_fn_t sctp_sf_do_6_3_3_rtx; | ||
173 | sctp_state_fn_t sctp_sf_do_6_2_sack; | ||
174 | sctp_state_fn_t sctp_sf_autoclose_timer_expire; | ||
175 | |||
176 | /* Prototypes for utility support functions. */ | ||
177 | __u8 sctp_get_chunk_type(struct sctp_chunk *chunk); | ||
178 | const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t, | ||
179 | sctp_state_t, | ||
180 | sctp_subtype_t); | ||
181 | int sctp_chunk_iif(const struct sctp_chunk *); | ||
182 | struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *, | ||
183 | struct sctp_chunk *, | ||
184 | int gfp); | ||
185 | __u32 sctp_generate_verification_tag(void); | ||
186 | void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag); | ||
187 | |||
188 | /* Prototypes for chunk-building functions. */ | ||
189 | struct sctp_chunk *sctp_make_init(const struct sctp_association *, | ||
190 | const struct sctp_bind_addr *, | ||
191 | int gfp, int vparam_len); | ||
192 | struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *, | ||
193 | const struct sctp_chunk *, | ||
194 | const int gfp, | ||
195 | const int unkparam_len); | ||
196 | struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *, | ||
197 | const struct sctp_chunk *); | ||
198 | struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *, | ||
199 | const struct sctp_chunk *); | ||
200 | struct sctp_chunk *sctp_make_cwr(const struct sctp_association *, | ||
201 | const __u32 lowest_tsn, | ||
202 | const struct sctp_chunk *); | ||
203 | struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *, | ||
204 | const struct sctp_sndrcvinfo *sinfo, | ||
205 | int len, const __u8 flags, | ||
206 | __u16 ssn); | ||
207 | struct sctp_chunk *sctp_make_ecne(const struct sctp_association *, | ||
208 | const __u32); | ||
209 | struct sctp_chunk *sctp_make_sack(const struct sctp_association *); | ||
210 | struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc, | ||
211 | const struct sctp_chunk *chunk); | ||
212 | struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc, | ||
213 | const struct sctp_chunk *); | ||
214 | struct sctp_chunk *sctp_make_shutdown_complete(const struct sctp_association *, | ||
215 | const struct sctp_chunk *); | ||
216 | void sctp_init_cause(struct sctp_chunk *, __u16 cause, const void *, size_t); | ||
217 | struct sctp_chunk *sctp_make_abort(const struct sctp_association *, | ||
218 | const struct sctp_chunk *, | ||
219 | const size_t hint); | ||
220 | struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *, | ||
221 | const struct sctp_chunk *, | ||
222 | __u32 tsn); | ||
223 | struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *, | ||
224 | const struct sctp_chunk *, | ||
225 | const struct msghdr *); | ||
226 | struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *, | ||
227 | const struct sctp_chunk *, | ||
228 | const __u8 *, | ||
229 | const size_t ); | ||
230 | struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *, | ||
231 | const struct sctp_transport *, | ||
232 | const void *payload, | ||
233 | const size_t paylen); | ||
234 | struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *, | ||
235 | const struct sctp_chunk *, | ||
236 | const void *payload, | ||
237 | const size_t paylen); | ||
238 | struct sctp_chunk *sctp_make_op_error(const struct sctp_association *, | ||
239 | const struct sctp_chunk *chunk, | ||
240 | __u16 cause_code, | ||
241 | const void *payload, | ||
242 | size_t paylen); | ||
243 | |||
244 | struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *, | ||
245 | union sctp_addr *, | ||
246 | struct sockaddr *, | ||
247 | int, __u16); | ||
248 | struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc, | ||
249 | union sctp_addr *addr); | ||
250 | struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, | ||
251 | struct sctp_chunk *asconf); | ||
252 | int sctp_process_asconf_ack(struct sctp_association *asoc, | ||
253 | struct sctp_chunk *asconf_ack); | ||
254 | struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, | ||
255 | __u32 new_cum_tsn, size_t nstreams, | ||
256 | struct sctp_fwdtsn_skip *skiplist); | ||
257 | |||
258 | void sctp_chunk_assign_tsn(struct sctp_chunk *); | ||
259 | void sctp_chunk_assign_ssn(struct sctp_chunk *); | ||
260 | |||
261 | void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error); | ||
262 | |||
263 | /* Prototypes for statetable processing. */ | ||
264 | |||
265 | int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype, | ||
266 | sctp_state_t state, | ||
267 | struct sctp_endpoint *, | ||
268 | struct sctp_association *asoc, | ||
269 | void *event_arg, | ||
270 | int gfp); | ||
271 | |||
272 | /* 2nd level prototypes */ | ||
273 | void sctp_generate_t3_rtx_event(unsigned long peer); | ||
274 | void sctp_generate_heartbeat_event(unsigned long peer); | ||
275 | |||
276 | void sctp_ootb_pkt_free(struct sctp_packet *); | ||
277 | |||
278 | struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *, | ||
279 | const struct sctp_association *, | ||
280 | struct sctp_chunk *, int gfp, int *err, | ||
281 | struct sctp_chunk **err_chk_p); | ||
282 | int sctp_addip_addr_config(struct sctp_association *, sctp_param_t, | ||
283 | struct sockaddr_storage*, int); | ||
284 | |||
285 | /* 3rd level prototypes */ | ||
286 | __u32 sctp_generate_tag(const struct sctp_endpoint *); | ||
287 | __u32 sctp_generate_tsn(const struct sctp_endpoint *); | ||
288 | |||
289 | /* Extern declarations for major data structures. */ | ||
290 | extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES]; | ||
291 | |||
292 | |||
293 | /* Get the size of a DATA chunk payload. */ | ||
294 | static inline __u16 sctp_data_size(struct sctp_chunk *chunk) | ||
295 | { | ||
296 | __u16 size; | ||
297 | |||
298 | size = ntohs(chunk->chunk_hdr->length); | ||
299 | size -= sizeof(sctp_data_chunk_t); | ||
300 | |||
301 | return size; | ||
302 | } | ||
303 | |||
304 | /* Compare two TSNs */ | ||
305 | |||
306 | /* RFC 1982 - Serial Number Arithmetic | ||
307 | * | ||
308 | * 2. Comparison | ||
309 | * Then, s1 is said to be equal to s2 if and only if i1 is equal to i2, | ||
310 | * in all other cases, s1 is not equal to s2. | ||
311 | * | ||
312 | * s1 is said to be less than s2 if, and only if, s1 is not equal to s2, | ||
313 | * and | ||
314 | * | ||
315 | * (i1 < i2 and i2 - i1 < 2^(SERIAL_BITS - 1)) or | ||
316 | * (i1 > i2 and i1 - i2 > 2^(SERIAL_BITS - 1)) | ||
317 | * | ||
318 | * s1 is said to be greater than s2 if, and only if, s1 is not equal to | ||
319 | * s2, and | ||
320 | * | ||
321 | * (i1 < i2 and i2 - i1 > 2^(SERIAL_BITS - 1)) or | ||
322 | * (i1 > i2 and i1 - i2 < 2^(SERIAL_BITS - 1)) | ||
323 | */ | ||
324 | |||
325 | /* | ||
326 | * RFC 2960 | ||
327 | * 1.6 Serial Number Arithmetic | ||
328 | * | ||
329 | * Comparisons and arithmetic on TSNs in this document SHOULD use Serial | ||
330 | * Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 32. | ||
331 | */ | ||
332 | |||
333 | enum { | ||
334 | TSN_SIGN_BIT = (1<<31) | ||
335 | }; | ||
336 | |||
337 | static inline int TSN_lt(__u32 s, __u32 t) | ||
338 | { | ||
339 | return (((s) - (t)) & TSN_SIGN_BIT); | ||
340 | } | ||
341 | |||
342 | static inline int TSN_lte(__u32 s, __u32 t) | ||
343 | { | ||
344 | return (((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT)); | ||
345 | } | ||
346 | |||
347 | /* Compare two SSNs */ | ||
348 | |||
349 | /* | ||
350 | * RFC 2960 | ||
351 | * 1.6 Serial Number Arithmetic | ||
352 | * | ||
353 | * Comparisons and arithmetic on Stream Sequence Numbers in this document | ||
354 | * SHOULD use Serial Number Arithmetic as defined in [RFC1982] where | ||
355 | * SERIAL_BITS = 16. | ||
356 | */ | ||
357 | enum { | ||
358 | SSN_SIGN_BIT = (1<<15) | ||
359 | }; | ||
360 | |||
361 | static inline int SSN_lt(__u16 s, __u16 t) | ||
362 | { | ||
363 | return (((s) - (t)) & SSN_SIGN_BIT); | ||
364 | } | ||
365 | |||
366 | static inline int SSN_lte(__u16 s, __u16 t) | ||
367 | { | ||
368 | return (((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT)); | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * ADDIP 3.1.1 | ||
373 | * The valid range of Serial Number is from 0 to 4294967295 (2**32 - 1). Serial | ||
374 | * Numbers wrap back to 0 after reaching 4294967295. | ||
375 | */ | ||
376 | enum { | ||
377 | ADDIP_SERIAL_SIGN_BIT = (1<<31) | ||
378 | }; | ||
379 | |||
380 | static inline int ADDIP_SERIAL_gte(__u16 s, __u16 t) | ||
381 | { | ||
382 | return (((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT)); | ||
383 | } | ||
384 | |||
385 | |||
386 | /* Run sctp_add_cmd() generating a BUG() if there is a failure. */ | ||
387 | static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj) | ||
388 | { | ||
389 | if (unlikely(!sctp_add_cmd(seq, verb, obj))) | ||
390 | BUG(); | ||
391 | } | ||
392 | |||
393 | /* Check VTAG of the packet matches the sender's own tag. */ | ||
394 | static inline int | ||
395 | sctp_vtag_verify(const struct sctp_chunk *chunk, | ||
396 | const struct sctp_association *asoc) | ||
397 | { | ||
398 | /* RFC 2960 Sec 8.5 When receiving an SCTP packet, the endpoint | ||
399 | * MUST ensure that the value in the Verification Tag field of | ||
400 | * the received SCTP packet matches its own Tag. If the received | ||
401 | * Verification Tag value does not match the receiver's own | ||
402 | * tag value, the receiver shall silently discard the packet... | ||
403 | */ | ||
404 | if (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag) | ||
405 | return 1; | ||
406 | |||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | /* Check VTAG of the packet matches the sender's own tag OR its peer's | ||
411 | * tag and the T bit is set in the Chunk Flags. | ||
412 | */ | ||
413 | static inline int | ||
414 | sctp_vtag_verify_either(const struct sctp_chunk *chunk, | ||
415 | const struct sctp_association *asoc) | ||
416 | { | ||
417 | /* RFC 2960 Section 8.5.1, sctpimpguide-06 Section 2.13.2 | ||
418 | * | ||
419 | * B) The receiver of a ABORT shall accept the packet if the | ||
420 | * Verification Tag field of the packet matches its own tag OR it | ||
421 | * is set to its peer's tag and the T bit is set in the Chunk | ||
422 | * Flags. Otherwise, the receiver MUST silently discard the packet | ||
423 | * and take no further action. | ||
424 | * | ||
425 | * (C) The receiver of a SHUTDOWN COMPLETE shall accept the | ||
426 | * packet if the Verification Tag field of the packet | ||
427 | * matches its own tag OR it is set to its peer's tag and | ||
428 | * the T bit is set in the Chunk Flags. Otherwise, the | ||
429 | * receiver MUST silently discard the packet and take no | ||
430 | * further action.... | ||
431 | * | ||
432 | */ | ||
433 | if ((ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag) || | ||
434 | (sctp_test_T_bit(chunk) && (ntohl(chunk->sctp_hdr->vtag) | ||
435 | == asoc->c.peer_vtag))) { | ||
436 | return 1; | ||
437 | } | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | #endif /* __sctp_sm_h__ */ | ||