141c99275SPeter Avalos /* Copyright (c) 2001 NETLAB, Temple University
241c99275SPeter Avalos * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware
341c99275SPeter Avalos *
441c99275SPeter Avalos * Jerry Heinz <gheinz@astro.temple.edu>
541c99275SPeter Avalos * John Fiore <jfiore@joda.cis.temple.edu>
641c99275SPeter Avalos * Armando L. Caro Jr. <acaro@cis.udel.edu>
741c99275SPeter Avalos *
841c99275SPeter Avalos * Redistribution and use in source and binary forms, with or without
941c99275SPeter Avalos * modification, are permitted provided that the following conditions
1041c99275SPeter Avalos * are met:
1141c99275SPeter Avalos *
1241c99275SPeter Avalos * 1. Redistributions of source code must retain the above copyright
1341c99275SPeter Avalos * notice, this list of conditions and the following disclaimer.
1441c99275SPeter Avalos *
1541c99275SPeter Avalos * 2. Redistributions in binary form must reproduce the above copyright
1641c99275SPeter Avalos * notice, this list of conditions and the following disclaimer in the
1741c99275SPeter Avalos * documentation and/or other materials provided with the distribution.
1841c99275SPeter Avalos *
1941c99275SPeter Avalos * 3. Neither the name of the University nor of the Laboratory may be used
2041c99275SPeter Avalos * to endorse or promote products derived from this software without
2141c99275SPeter Avalos * specific prior written permission.
2241c99275SPeter Avalos *
2341c99275SPeter Avalos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2441c99275SPeter Avalos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2541c99275SPeter Avalos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2641c99275SPeter Avalos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2741c99275SPeter Avalos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2841c99275SPeter Avalos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2941c99275SPeter Avalos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3041c99275SPeter Avalos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3141c99275SPeter Avalos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3241c99275SPeter Avalos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3341c99275SPeter Avalos * SUCH DAMAGE.
3441c99275SPeter Avalos */
3541c99275SPeter Avalos
36411677aeSAaron LI /* \summary: Stream Control Transmission Protocol (SCTP) printer */
3741c99275SPeter Avalos
3841c99275SPeter Avalos #ifdef HAVE_CONFIG_H
39*ed775ee7SAntonio Huete Jimenez #include <config.h>
4041c99275SPeter Avalos #endif
4141c99275SPeter Avalos
42*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
4341c99275SPeter Avalos
44411677aeSAaron LI #include "netdissect.h"
4541c99275SPeter Avalos #include "addrtoname.h"
46411677aeSAaron LI #include "extract.h"
4741c99275SPeter Avalos #include "ip.h"
4841c99275SPeter Avalos #include "ip6.h"
49411677aeSAaron LI
50411677aeSAaron LI /* Definitions from:
51411677aeSAaron LI *
52411677aeSAaron LI * SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola
53411677aeSAaron LI *
54411677aeSAaron LI * Redistribution and use in source and binary forms, with or without
55411677aeSAaron LI * modification, are permitted provided that the following conditions
56411677aeSAaron LI * are met:
57411677aeSAaron LI *
58411677aeSAaron LI * 1. Redistributions of source code must retain the above copyright
59411677aeSAaron LI * notice, this list of conditions and the following disclaimer.
60411677aeSAaron LI *
61411677aeSAaron LI * 2. Redistributions in binary form must reproduce the above copyright
62411677aeSAaron LI * notice, this list of conditions and the following disclaimer in the
63411677aeSAaron LI * documentation and/or other materials provided with the distribution.
64411677aeSAaron LI *
65411677aeSAaron LI * 3. Neither the name of Cisco nor of Motorola may be used
66411677aeSAaron LI * to endorse or promote products derived from this software without
67411677aeSAaron LI * specific prior written permission.
68411677aeSAaron LI *
69411677aeSAaron LI * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
70411677aeSAaron LI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
71411677aeSAaron LI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
72411677aeSAaron LI * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
73411677aeSAaron LI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
74411677aeSAaron LI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
75411677aeSAaron LI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
76411677aeSAaron LI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
77411677aeSAaron LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
78411677aeSAaron LI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
79411677aeSAaron LI * SUCH DAMAGE.
80411677aeSAaron LI *
81411677aeSAaron LI * This file is part of the SCTP reference Implementation
82411677aeSAaron LI *
83411677aeSAaron LI *
84411677aeSAaron LI * Please send any bug reports or fixes you make to one of the following email
85411677aeSAaron LI * addresses:
86411677aeSAaron LI *
87411677aeSAaron LI * rstewar1@email.mot.com
88411677aeSAaron LI * kmorneau@cisco.com
89411677aeSAaron LI * qxie1@email.mot.com
90411677aeSAaron LI *
91411677aeSAaron LI * Any bugs reported given to us we will try to fix... any fixes shared will
92*ed775ee7SAntonio Huete Jimenez * be incorporated into the next SCTP release.
93411677aeSAaron LI */
94411677aeSAaron LI
95411677aeSAaron LI /* The valid defines for all message
96411677aeSAaron LI * types know to SCTP. 0 is reserved
97411677aeSAaron LI */
98411677aeSAaron LI #define SCTP_DATA 0x00
99411677aeSAaron LI #define SCTP_INITIATION 0x01
100411677aeSAaron LI #define SCTP_INITIATION_ACK 0x02
101411677aeSAaron LI #define SCTP_SELECTIVE_ACK 0x03
102411677aeSAaron LI #define SCTP_HEARTBEAT_REQUEST 0x04
103411677aeSAaron LI #define SCTP_HEARTBEAT_ACK 0x05
104411677aeSAaron LI #define SCTP_ABORT_ASSOCIATION 0x06
105411677aeSAaron LI #define SCTP_SHUTDOWN 0x07
106411677aeSAaron LI #define SCTP_SHUTDOWN_ACK 0x08
107411677aeSAaron LI #define SCTP_OPERATION_ERR 0x09
108411677aeSAaron LI #define SCTP_COOKIE_ECHO 0x0a
109411677aeSAaron LI #define SCTP_COOKIE_ACK 0x0b
110411677aeSAaron LI #define SCTP_ECN_ECHO 0x0c
111411677aeSAaron LI #define SCTP_ECN_CWR 0x0d
112411677aeSAaron LI #define SCTP_SHUTDOWN_COMPLETE 0x0e
113411677aeSAaron LI #define SCTP_FORWARD_CUM_TSN 0xc0
114411677aeSAaron LI #define SCTP_RELIABLE_CNTL 0xc1
115411677aeSAaron LI #define SCTP_RELIABLE_CNTL_ACK 0xc2
116411677aeSAaron LI
117411677aeSAaron LI static const struct tok sctp_chunkid_str[] = {
118411677aeSAaron LI { SCTP_DATA, "DATA" },
119411677aeSAaron LI { SCTP_INITIATION, "INIT" },
120411677aeSAaron LI { SCTP_INITIATION_ACK, "INIT ACK" },
121411677aeSAaron LI { SCTP_SELECTIVE_ACK, "SACK" },
122411677aeSAaron LI { SCTP_HEARTBEAT_REQUEST, "HB REQ" },
123411677aeSAaron LI { SCTP_HEARTBEAT_ACK, "HB ACK" },
124411677aeSAaron LI { SCTP_ABORT_ASSOCIATION, "ABORT" },
125411677aeSAaron LI { SCTP_SHUTDOWN, "SHUTDOWN" },
126411677aeSAaron LI { SCTP_SHUTDOWN_ACK, "SHUTDOWN ACK" },
127411677aeSAaron LI { SCTP_OPERATION_ERR, "OP ERR" },
128411677aeSAaron LI { SCTP_COOKIE_ECHO, "COOKIE ECHO" },
129411677aeSAaron LI { SCTP_COOKIE_ACK, "COOKIE ACK" },
130411677aeSAaron LI { SCTP_ECN_ECHO, "ECN ECHO" },
131411677aeSAaron LI { SCTP_ECN_CWR, "ECN CWR" },
132411677aeSAaron LI { SCTP_SHUTDOWN_COMPLETE, "SHUTDOWN COMPLETE" },
133411677aeSAaron LI { SCTP_FORWARD_CUM_TSN, "FOR CUM TSN" },
134411677aeSAaron LI { SCTP_RELIABLE_CNTL, "REL CTRL" },
135411677aeSAaron LI { SCTP_RELIABLE_CNTL_ACK, "REL CTRL ACK" },
136411677aeSAaron LI { 0, NULL }
137411677aeSAaron LI };
138411677aeSAaron LI
139411677aeSAaron LI /* Data Chuck Specific Flags */
140411677aeSAaron LI #define SCTP_DATA_FRAG_MASK 0x03
141411677aeSAaron LI #define SCTP_DATA_MIDDLE_FRAG 0x00
142411677aeSAaron LI #define SCTP_DATA_LAST_FRAG 0x01
143411677aeSAaron LI #define SCTP_DATA_FIRST_FRAG 0x02
144411677aeSAaron LI #define SCTP_DATA_NOT_FRAG 0x03
145411677aeSAaron LI #define SCTP_DATA_UNORDERED 0x04
146411677aeSAaron LI
147411677aeSAaron LI #define SCTP_ADDRMAX 60
14841c99275SPeter Avalos
14927bfbee1SPeter Avalos #define CHAN_HP 6704
15027bfbee1SPeter Avalos #define CHAN_MP 6705
15127bfbee1SPeter Avalos #define CHAN_LP 6706
15227bfbee1SPeter Avalos
153411677aeSAaron LI /* the sctp common header */
154411677aeSAaron LI
155411677aeSAaron LI struct sctpHeader{
156*ed775ee7SAntonio Huete Jimenez nd_uint16_t source;
157*ed775ee7SAntonio Huete Jimenez nd_uint16_t destination;
158*ed775ee7SAntonio Huete Jimenez nd_uint32_t verificationTag;
159*ed775ee7SAntonio Huete Jimenez nd_uint32_t adler32;
160411677aeSAaron LI };
161411677aeSAaron LI
162411677aeSAaron LI /* various descriptor parsers */
163411677aeSAaron LI
164411677aeSAaron LI struct sctpChunkDesc{
165*ed775ee7SAntonio Huete Jimenez nd_uint8_t chunkID;
166*ed775ee7SAntonio Huete Jimenez nd_uint8_t chunkFlg;
167*ed775ee7SAntonio Huete Jimenez nd_uint16_t chunkLength;
168411677aeSAaron LI };
169411677aeSAaron LI
170411677aeSAaron LI struct sctpParamDesc{
171*ed775ee7SAntonio Huete Jimenez nd_uint16_t paramType;
172*ed775ee7SAntonio Huete Jimenez nd_uint16_t paramLength;
173411677aeSAaron LI };
174411677aeSAaron LI
175411677aeSAaron LI
176411677aeSAaron LI struct sctpRelChunkDesc{
177411677aeSAaron LI struct sctpChunkDesc chk;
178*ed775ee7SAntonio Huete Jimenez nd_uint32_t serialNumber;
179411677aeSAaron LI };
180411677aeSAaron LI
181411677aeSAaron LI struct sctpVendorSpecificParam {
182411677aeSAaron LI struct sctpParamDesc p; /* type must be 0xfffe */
183*ed775ee7SAntonio Huete Jimenez nd_uint32_t vendorId; /* vendor ID from RFC 1700 */
184*ed775ee7SAntonio Huete Jimenez nd_uint16_t vendorSpecificType;
185*ed775ee7SAntonio Huete Jimenez nd_uint16_t vendorSpecificLen;
186411677aeSAaron LI };
187411677aeSAaron LI
188411677aeSAaron LI
189411677aeSAaron LI /* Structures for the control parts */
190411677aeSAaron LI
191411677aeSAaron LI
192411677aeSAaron LI
193411677aeSAaron LI /* Sctp association init request/ack */
194411677aeSAaron LI
195411677aeSAaron LI /* this is used for init ack, too */
196411677aeSAaron LI struct sctpInitiation{
197*ed775ee7SAntonio Huete Jimenez nd_uint32_t initTag; /* tag of mine */
198*ed775ee7SAntonio Huete Jimenez nd_uint32_t rcvWindowCredit; /* rwnd */
199*ed775ee7SAntonio Huete Jimenez nd_uint16_t NumPreopenStreams; /* OS */
200*ed775ee7SAntonio Huete Jimenez nd_uint16_t MaxInboundStreams; /* MIS */
201*ed775ee7SAntonio Huete Jimenez nd_uint32_t initialTSN;
202411677aeSAaron LI /* optional param's follow in sctpParamDesc form */
203411677aeSAaron LI };
204411677aeSAaron LI
205411677aeSAaron LI struct sctpV4IpAddress{
206411677aeSAaron LI struct sctpParamDesc p; /* type is set to SCTP_IPV4_PARAM_TYPE, len=10 */
207*ed775ee7SAntonio Huete Jimenez nd_ipv4 ipAddress;
208411677aeSAaron LI };
209411677aeSAaron LI
210411677aeSAaron LI
211411677aeSAaron LI struct sctpV6IpAddress{
212411677aeSAaron LI struct sctpParamDesc p; /* type is set to SCTP_IPV6_PARAM_TYPE, len=22 */
213*ed775ee7SAntonio Huete Jimenez nd_ipv6 ipAddress;
214411677aeSAaron LI };
215411677aeSAaron LI
216411677aeSAaron LI struct sctpDNSName{
217411677aeSAaron LI struct sctpParamDesc param;
218*ed775ee7SAntonio Huete Jimenez nd_byte name[1];
219411677aeSAaron LI };
220411677aeSAaron LI
221411677aeSAaron LI
222411677aeSAaron LI struct sctpCookiePreserve{
223411677aeSAaron LI struct sctpParamDesc p; /* type is set to SCTP_COOKIE_PRESERVE, len=8 */
224*ed775ee7SAntonio Huete Jimenez nd_uint32_t extraTime;
225411677aeSAaron LI };
226411677aeSAaron LI
227411677aeSAaron LI
228411677aeSAaron LI struct sctpTimeStamp{
229*ed775ee7SAntonio Huete Jimenez nd_uint32_t ts_sec;
230*ed775ee7SAntonio Huete Jimenez nd_uint32_t ts_usec;
231411677aeSAaron LI };
232411677aeSAaron LI
233411677aeSAaron LI
234411677aeSAaron LI /* this guy is for use when
235411677aeSAaron LI * I have a initiate message gloming the
236411677aeSAaron LI * things together.
237411677aeSAaron LI
238411677aeSAaron LI */
239411677aeSAaron LI struct sctpUnifiedInit{
240411677aeSAaron LI struct sctpChunkDesc uh;
241411677aeSAaron LI struct sctpInitiation initm;
242411677aeSAaron LI };
243411677aeSAaron LI
244411677aeSAaron LI struct sctpSendableInit{
245411677aeSAaron LI struct sctpHeader mh;
246411677aeSAaron LI struct sctpUnifiedInit msg;
247411677aeSAaron LI };
248411677aeSAaron LI
249411677aeSAaron LI
250411677aeSAaron LI /* Selective Acknowledgement
251411677aeSAaron LI * has the following structure with
252*ed775ee7SAntonio Huete Jimenez * a optional amount of trailing int's
253411677aeSAaron LI * on the last part (based on the numberOfDesc
254411677aeSAaron LI * field).
255411677aeSAaron LI */
256411677aeSAaron LI
257411677aeSAaron LI struct sctpSelectiveAck{
258*ed775ee7SAntonio Huete Jimenez nd_uint32_t highestConseqTSN;
259*ed775ee7SAntonio Huete Jimenez nd_uint32_t updatedRwnd;
260*ed775ee7SAntonio Huete Jimenez nd_uint16_t numberOfdesc;
261*ed775ee7SAntonio Huete Jimenez nd_uint16_t numDupTsns;
262411677aeSAaron LI };
263411677aeSAaron LI
264411677aeSAaron LI struct sctpSelectiveFrag{
265*ed775ee7SAntonio Huete Jimenez nd_uint16_t fragmentStart;
266*ed775ee7SAntonio Huete Jimenez nd_uint16_t fragmentEnd;
267411677aeSAaron LI };
268411677aeSAaron LI
269411677aeSAaron LI
270411677aeSAaron LI struct sctpUnifiedSack{
271411677aeSAaron LI struct sctpChunkDesc uh;
272411677aeSAaron LI struct sctpSelectiveAck sack;
273411677aeSAaron LI };
274411677aeSAaron LI
275411677aeSAaron LI /* for the abort and shutdown ACK
276411677aeSAaron LI * we must carry the init tag in the common header. Just the
277411677aeSAaron LI * common header is all that is needed with a chunk descriptor.
278411677aeSAaron LI */
279411677aeSAaron LI struct sctpUnifiedAbort{
280411677aeSAaron LI struct sctpChunkDesc uh;
281411677aeSAaron LI };
282411677aeSAaron LI
283411677aeSAaron LI struct sctpUnifiedAbortLight{
284411677aeSAaron LI struct sctpHeader mh;
285411677aeSAaron LI struct sctpChunkDesc uh;
286411677aeSAaron LI };
287411677aeSAaron LI
288411677aeSAaron LI struct sctpUnifiedAbortHeavy{
289411677aeSAaron LI struct sctpHeader mh;
290411677aeSAaron LI struct sctpChunkDesc uh;
291*ed775ee7SAntonio Huete Jimenez nd_uint16_t causeCode;
292*ed775ee7SAntonio Huete Jimenez nd_uint16_t causeLen;
293411677aeSAaron LI };
294411677aeSAaron LI
295411677aeSAaron LI /* For the graceful shutdown we must carry
296411677aeSAaron LI * the tag (in common header) and the highest consequitive acking value
297411677aeSAaron LI */
298411677aeSAaron LI struct sctpShutdown {
299*ed775ee7SAntonio Huete Jimenez nd_uint32_t TSN_Seen;
300411677aeSAaron LI };
301411677aeSAaron LI
302411677aeSAaron LI struct sctpUnifiedShutdown{
303411677aeSAaron LI struct sctpChunkDesc uh;
304411677aeSAaron LI struct sctpShutdown shut;
305411677aeSAaron LI };
306411677aeSAaron LI
307411677aeSAaron LI /* in the unified message we add the trailing
308411677aeSAaron LI * stream id since it is the only message
309411677aeSAaron LI * that is defined as a operation error.
310411677aeSAaron LI */
311411677aeSAaron LI struct sctpOpErrorCause{
312*ed775ee7SAntonio Huete Jimenez nd_uint16_t cause;
313*ed775ee7SAntonio Huete Jimenez nd_uint16_t causeLen;
314411677aeSAaron LI };
315411677aeSAaron LI
316411677aeSAaron LI struct sctpUnifiedOpError{
317411677aeSAaron LI struct sctpChunkDesc uh;
318411677aeSAaron LI struct sctpOpErrorCause c;
319411677aeSAaron LI };
320411677aeSAaron LI
321411677aeSAaron LI struct sctpUnifiedStreamError{
322411677aeSAaron LI struct sctpHeader mh;
323411677aeSAaron LI struct sctpChunkDesc uh;
324411677aeSAaron LI struct sctpOpErrorCause c;
325*ed775ee7SAntonio Huete Jimenez nd_uint16_t strmNum;
326*ed775ee7SAntonio Huete Jimenez nd_uint16_t reserved;
327411677aeSAaron LI };
328411677aeSAaron LI
329411677aeSAaron LI struct staleCookieMsg{
330411677aeSAaron LI struct sctpHeader mh;
331411677aeSAaron LI struct sctpChunkDesc uh;
332411677aeSAaron LI struct sctpOpErrorCause c;
333*ed775ee7SAntonio Huete Jimenez nd_uint32_t moretime;
334411677aeSAaron LI };
335411677aeSAaron LI
336411677aeSAaron LI /* the following is used in all sends
337411677aeSAaron LI * where nothing is needed except the
338411677aeSAaron LI * chunk/type i.e. shutdownAck Abort */
339411677aeSAaron LI
340411677aeSAaron LI struct sctpUnifiedSingleMsg{
341411677aeSAaron LI struct sctpHeader mh;
342411677aeSAaron LI struct sctpChunkDesc uh;
343411677aeSAaron LI };
344411677aeSAaron LI
345411677aeSAaron LI struct sctpDataPart{
346*ed775ee7SAntonio Huete Jimenez nd_uint32_t TSN;
347*ed775ee7SAntonio Huete Jimenez nd_uint16_t streamId;
348*ed775ee7SAntonio Huete Jimenez nd_uint16_t sequence;
349*ed775ee7SAntonio Huete Jimenez nd_uint32_t payloadtype;
350411677aeSAaron LI };
351411677aeSAaron LI
352411677aeSAaron LI struct sctpUnifiedDatagram{
353411677aeSAaron LI struct sctpChunkDesc uh;
354411677aeSAaron LI struct sctpDataPart dp;
355411677aeSAaron LI };
356411677aeSAaron LI
357411677aeSAaron LI struct sctpECN_echo{
358411677aeSAaron LI struct sctpChunkDesc uh;
359*ed775ee7SAntonio Huete Jimenez nd_uint32_t Lowest_TSN;
360411677aeSAaron LI };
361411677aeSAaron LI
362411677aeSAaron LI
363411677aeSAaron LI struct sctpCWR{
364411677aeSAaron LI struct sctpChunkDesc uh;
365*ed775ee7SAntonio Huete Jimenez nd_uint32_t TSN_reduced_at;
366411677aeSAaron LI };
367411677aeSAaron LI
368411677aeSAaron LI static const struct tok ForCES_channels[] = {
36927bfbee1SPeter Avalos { CHAN_HP, "ForCES HP" },
37027bfbee1SPeter Avalos { CHAN_MP, "ForCES MP" },
37127bfbee1SPeter Avalos { CHAN_LP, "ForCES LP" },
37227bfbee1SPeter Avalos { 0, NULL }
37327bfbee1SPeter Avalos };
37427bfbee1SPeter Avalos
375411677aeSAaron LI /* data chunk's payload protocol identifiers */
376411677aeSAaron LI
377411677aeSAaron LI #define SCTP_PPID_IUA 1
378411677aeSAaron LI #define SCTP_PPID_M2UA 2
379411677aeSAaron LI #define SCTP_PPID_M3UA 3
380411677aeSAaron LI #define SCTP_PPID_SUA 4
381411677aeSAaron LI #define SCTP_PPID_M2PA 5
382411677aeSAaron LI #define SCTP_PPID_V5UA 6
383411677aeSAaron LI #define SCTP_PPID_H248 7
384411677aeSAaron LI #define SCTP_PPID_BICC 8
385411677aeSAaron LI #define SCTP_PPID_TALI 9
386411677aeSAaron LI #define SCTP_PPID_DUA 10
387411677aeSAaron LI #define SCTP_PPID_ASAP 11
388411677aeSAaron LI #define SCTP_PPID_ENRP 12
389411677aeSAaron LI #define SCTP_PPID_H323 13
390411677aeSAaron LI #define SCTP_PPID_QIPC 14
391411677aeSAaron LI #define SCTP_PPID_SIMCO 15
392411677aeSAaron LI #define SCTP_PPID_DDPSC 16
393411677aeSAaron LI #define SCTP_PPID_DDPSSC 17
394411677aeSAaron LI #define SCTP_PPID_S1AP 18
395411677aeSAaron LI #define SCTP_PPID_RUA 19
396411677aeSAaron LI #define SCTP_PPID_HNBAP 20
397411677aeSAaron LI #define SCTP_PPID_FORCES_HP 21
398411677aeSAaron LI #define SCTP_PPID_FORCES_MP 22
399411677aeSAaron LI #define SCTP_PPID_FORCES_LP 23
400411677aeSAaron LI #define SCTP_PPID_SBC_AP 24
401411677aeSAaron LI #define SCTP_PPID_NBAP 25
402411677aeSAaron LI /* 26 */
403411677aeSAaron LI #define SCTP_PPID_X2AP 27
404411677aeSAaron LI
405411677aeSAaron LI static const struct tok PayloadProto_idents[] = {
406411677aeSAaron LI { SCTP_PPID_IUA, "ISDN Q.921" },
407411677aeSAaron LI { SCTP_PPID_M2UA, "M2UA" },
408411677aeSAaron LI { SCTP_PPID_M3UA, "M3UA" },
409411677aeSAaron LI { SCTP_PPID_SUA, "SUA" },
410411677aeSAaron LI { SCTP_PPID_M2PA, "M2PA" },
411411677aeSAaron LI { SCTP_PPID_V5UA, "V5.2" },
412411677aeSAaron LI { SCTP_PPID_H248, "H.248" },
413411677aeSAaron LI { SCTP_PPID_BICC, "BICC" },
414411677aeSAaron LI { SCTP_PPID_TALI, "TALI" },
415411677aeSAaron LI { SCTP_PPID_DUA, "DUA" },
416411677aeSAaron LI { SCTP_PPID_ASAP, "ASAP" },
417411677aeSAaron LI { SCTP_PPID_ENRP, "ENRP" },
418411677aeSAaron LI { SCTP_PPID_H323, "H.323" },
419411677aeSAaron LI { SCTP_PPID_QIPC, "Q.IPC" },
420411677aeSAaron LI { SCTP_PPID_SIMCO, "SIMCO" },
421411677aeSAaron LI { SCTP_PPID_DDPSC, "DDPSC" },
422411677aeSAaron LI { SCTP_PPID_DDPSSC, "DDPSSC" },
423411677aeSAaron LI { SCTP_PPID_S1AP, "S1AP" },
424411677aeSAaron LI { SCTP_PPID_RUA, "RUA" },
425411677aeSAaron LI { SCTP_PPID_HNBAP, "HNBAP" },
426411677aeSAaron LI { SCTP_PPID_FORCES_HP, "ForCES HP" },
427411677aeSAaron LI { SCTP_PPID_FORCES_MP, "ForCES MP" },
428411677aeSAaron LI { SCTP_PPID_FORCES_LP, "ForCES LP" },
429411677aeSAaron LI { SCTP_PPID_SBC_AP, "SBc-AP" },
430411677aeSAaron LI { SCTP_PPID_NBAP, "NBAP" },
431411677aeSAaron LI /* 26 */
432411677aeSAaron LI { SCTP_PPID_X2AP, "X2AP" },
433411677aeSAaron LI { 0, NULL }
434411677aeSAaron LI };
435411677aeSAaron LI
436411677aeSAaron LI
437*ed775ee7SAntonio Huete Jimenez static int
isForCES_port(u_short Port)438*ed775ee7SAntonio Huete Jimenez isForCES_port(u_short Port)
43927bfbee1SPeter Avalos {
44027bfbee1SPeter Avalos if (Port == CHAN_HP)
44127bfbee1SPeter Avalos return 1;
44227bfbee1SPeter Avalos if (Port == CHAN_MP)
44327bfbee1SPeter Avalos return 1;
44427bfbee1SPeter Avalos if (Port == CHAN_LP)
44527bfbee1SPeter Avalos return 1;
44627bfbee1SPeter Avalos
44727bfbee1SPeter Avalos return 0;
44827bfbee1SPeter Avalos }
44927bfbee1SPeter Avalos
450*ed775ee7SAntonio Huete Jimenez void
sctp_print(netdissect_options * ndo,const u_char * bp,const u_char * bp2,u_int sctpPacketLength)451*ed775ee7SAntonio Huete Jimenez sctp_print(netdissect_options *ndo,
452411677aeSAaron LI const u_char *bp, /* beginning of sctp packet */
45341c99275SPeter Avalos const u_char *bp2, /* beginning of enclosing */
45441c99275SPeter Avalos u_int sctpPacketLength) /* ip packet */
45541c99275SPeter Avalos {
456411677aeSAaron LI u_int sctpPacketLengthRemaining;
45741c99275SPeter Avalos const struct sctpHeader *sctpPktHdr;
45841c99275SPeter Avalos const struct ip *ip;
45941c99275SPeter Avalos const struct ip6_hdr *ip6;
460*ed775ee7SAntonio Huete Jimenez uint8_t chunkID;
46141c99275SPeter Avalos u_short sourcePort, destPort;
462*ed775ee7SAntonio Huete Jimenez u_int chunkCount;
46341c99275SPeter Avalos const struct sctpChunkDesc *chunkDescPtr;
46441c99275SPeter Avalos const char *sep;
46527bfbee1SPeter Avalos int isforces = 0;
46627bfbee1SPeter Avalos
467*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "sctp";
46841c99275SPeter Avalos if (sctpPacketLength < sizeof(struct sctpHeader))
46941c99275SPeter Avalos {
470*ed775ee7SAntonio Huete Jimenez ND_PRINT("truncated-sctp - %zu bytes missing!",
471*ed775ee7SAntonio Huete Jimenez sizeof(struct sctpHeader) - sctpPacketLength);
47241c99275SPeter Avalos return;
47341c99275SPeter Avalos }
474411677aeSAaron LI sctpPktHdr = (const struct sctpHeader*) bp;
475*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(sctpPktHdr);
476411677aeSAaron LI sctpPacketLengthRemaining = sctpPacketLength;
47741c99275SPeter Avalos
478*ed775ee7SAntonio Huete Jimenez sourcePort = GET_BE_U_2(sctpPktHdr->source);
479*ed775ee7SAntonio Huete Jimenez destPort = GET_BE_U_2(sctpPktHdr->destination);
48041c99275SPeter Avalos
481411677aeSAaron LI ip = (const struct ip *)bp2;
482411677aeSAaron LI if (IP_V(ip) == 6)
483411677aeSAaron LI ip6 = (const struct ip6_hdr *)bp2;
484411677aeSAaron LI else
485411677aeSAaron LI ip6 = NULL;
486411677aeSAaron LI
48741c99275SPeter Avalos if (ip6) {
488*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s.%u > %s.%u: sctp",
489*ed775ee7SAntonio Huete Jimenez GET_IP6ADDR_STRING(ip6->ip6_src),
49041c99275SPeter Avalos sourcePort,
491*ed775ee7SAntonio Huete Jimenez GET_IP6ADDR_STRING(ip6->ip6_dst),
492*ed775ee7SAntonio Huete Jimenez destPort);
493*ed775ee7SAntonio Huete Jimenez } else {
494*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s.%u > %s.%u: sctp",
495*ed775ee7SAntonio Huete Jimenez GET_IPADDR_STRING(ip->ip_src),
49641c99275SPeter Avalos sourcePort,
497*ed775ee7SAntonio Huete Jimenez GET_IPADDR_STRING(ip->ip_dst),
498*ed775ee7SAntonio Huete Jimenez destPort);
49941c99275SPeter Avalos }
50041c99275SPeter Avalos
50127bfbee1SPeter Avalos if (isForCES_port(sourcePort)) {
502*ed775ee7SAntonio Huete Jimenez ND_PRINT("[%s]", tok2str(ForCES_channels, NULL, sourcePort));
50327bfbee1SPeter Avalos isforces = 1;
50427bfbee1SPeter Avalos }
50527bfbee1SPeter Avalos if (isForCES_port(destPort)) {
506*ed775ee7SAntonio Huete Jimenez ND_PRINT("[%s]", tok2str(ForCES_channels, NULL, destPort));
50727bfbee1SPeter Avalos isforces = 1;
50827bfbee1SPeter Avalos }
50927bfbee1SPeter Avalos
510411677aeSAaron LI bp += sizeof(struct sctpHeader);
511411677aeSAaron LI sctpPacketLengthRemaining -= sizeof(struct sctpHeader);
512411677aeSAaron LI
513411677aeSAaron LI if (ndo->ndo_vflag >= 2)
51441c99275SPeter Avalos sep = "\n\t";
51541c99275SPeter Avalos else
51641c99275SPeter Avalos sep = " (";
51741c99275SPeter Avalos /* cycle through all chunks, printing information on each one */
518411677aeSAaron LI for (chunkCount = 0, chunkDescPtr = (const struct sctpChunkDesc *)bp;
519411677aeSAaron LI sctpPacketLengthRemaining != 0;
520411677aeSAaron LI chunkCount++)
52141c99275SPeter Avalos {
522411677aeSAaron LI uint16_t chunkLength, chunkLengthRemaining;
523411677aeSAaron LI uint16_t align;
52441c99275SPeter Avalos
525411677aeSAaron LI chunkDescPtr = (const struct sctpChunkDesc *)bp;
526411677aeSAaron LI if (sctpPacketLengthRemaining < sizeof(*chunkDescPtr)) {
527*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s%u) [chunk descriptor cut off at end of packet]", sep, chunkCount+1);
52841c99275SPeter Avalos break;
52941c99275SPeter Avalos }
530*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(chunkDescPtr);
531*ed775ee7SAntonio Huete Jimenez chunkLength = GET_BE_U_2(chunkDescPtr->chunkLength);
532411677aeSAaron LI if (chunkLength < sizeof(*chunkDescPtr)) {
533*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s%u) [Bad chunk length %u, < size of chunk descriptor]", sep, chunkCount+1, chunkLength);
534411677aeSAaron LI break;
535411677aeSAaron LI }
536411677aeSAaron LI chunkLengthRemaining = chunkLength;
53741c99275SPeter Avalos
53841c99275SPeter Avalos align = chunkLength % 4;
53941c99275SPeter Avalos if (align != 0)
54041c99275SPeter Avalos align = 4 - align;
54141c99275SPeter Avalos
542411677aeSAaron LI if (sctpPacketLengthRemaining < align) {
543*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s%u) [Bad chunk length %u, > remaining data in packet]", sep, chunkCount+1, chunkLength);
544411677aeSAaron LI break;
545411677aeSAaron LI }
54641c99275SPeter Avalos
547*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(bp, chunkLength);
548411677aeSAaron LI
549411677aeSAaron LI bp += sizeof(*chunkDescPtr);
550411677aeSAaron LI sctpPacketLengthRemaining -= sizeof(*chunkDescPtr);
551411677aeSAaron LI chunkLengthRemaining -= sizeof(*chunkDescPtr);
552411677aeSAaron LI
553*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s%u) ", sep, chunkCount+1);
554*ed775ee7SAntonio Huete Jimenez chunkID = GET_U_1(chunkDescPtr->chunkID);
555*ed775ee7SAntonio Huete Jimenez ND_PRINT("[%s] ", tok2str(sctp_chunkid_str, "Unknown chunk type: 0x%x",
556*ed775ee7SAntonio Huete Jimenez chunkID));
557*ed775ee7SAntonio Huete Jimenez switch (chunkID)
55841c99275SPeter Avalos {
55941c99275SPeter Avalos case SCTP_DATA :
56041c99275SPeter Avalos {
56141c99275SPeter Avalos const struct sctpDataPart *dataHdrPtr;
562*ed775ee7SAntonio Huete Jimenez uint8_t chunkFlg;
563411677aeSAaron LI uint32_t ppid;
564*ed775ee7SAntonio Huete Jimenez uint16_t payload_size;
56541c99275SPeter Avalos
566*ed775ee7SAntonio Huete Jimenez chunkFlg = GET_U_1(chunkDescPtr->chunkFlg);
567*ed775ee7SAntonio Huete Jimenez if ((chunkFlg & SCTP_DATA_UNORDERED) == SCTP_DATA_UNORDERED)
568*ed775ee7SAntonio Huete Jimenez ND_PRINT("(U)");
56941c99275SPeter Avalos
570*ed775ee7SAntonio Huete Jimenez if ((chunkFlg & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG)
571*ed775ee7SAntonio Huete Jimenez ND_PRINT("(B)");
57241c99275SPeter Avalos
573*ed775ee7SAntonio Huete Jimenez if ((chunkFlg & SCTP_DATA_LAST_FRAG) == SCTP_DATA_LAST_FRAG)
574*ed775ee7SAntonio Huete Jimenez ND_PRINT("(E)");
57541c99275SPeter Avalos
576*ed775ee7SAntonio Huete Jimenez if( ((chunkFlg & SCTP_DATA_UNORDERED) == SCTP_DATA_UNORDERED) ||
577*ed775ee7SAntonio Huete Jimenez ((chunkFlg & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG) ||
578*ed775ee7SAntonio Huete Jimenez ((chunkFlg & SCTP_DATA_LAST_FRAG) == SCTP_DATA_LAST_FRAG) )
579*ed775ee7SAntonio Huete Jimenez ND_PRINT(" ");
58041c99275SPeter Avalos
581411677aeSAaron LI if (chunkLengthRemaining < sizeof(*dataHdrPtr)) {
582*ed775ee7SAntonio Huete Jimenez ND_PRINT("bogus chunk length %u]", chunkLength);
583411677aeSAaron LI return;
584411677aeSAaron LI }
585411677aeSAaron LI dataHdrPtr=(const struct sctpDataPart*)bp;
58641c99275SPeter Avalos
587*ed775ee7SAntonio Huete Jimenez ppid = GET_BE_U_4(dataHdrPtr->payloadtype);
588*ed775ee7SAntonio Huete Jimenez ND_PRINT("[TSN: %u] ", GET_BE_U_4(dataHdrPtr->TSN));
589*ed775ee7SAntonio Huete Jimenez ND_PRINT("[SID: %u] ", GET_BE_U_2(dataHdrPtr->streamId));
590*ed775ee7SAntonio Huete Jimenez ND_PRINT("[SSEQ %u] ", GET_BE_U_2(dataHdrPtr->sequence));
591*ed775ee7SAntonio Huete Jimenez ND_PRINT("[PPID %s] ",
592*ed775ee7SAntonio Huete Jimenez tok2str(PayloadProto_idents, "0x%x", ppid));
593411677aeSAaron LI
594411677aeSAaron LI if (!isforces) {
595411677aeSAaron LI isforces = (ppid == SCTP_PPID_FORCES_HP) ||
596411677aeSAaron LI (ppid == SCTP_PPID_FORCES_MP) ||
597411677aeSAaron LI (ppid == SCTP_PPID_FORCES_LP);
598411677aeSAaron LI }
599411677aeSAaron LI
600411677aeSAaron LI bp += sizeof(*dataHdrPtr);
601411677aeSAaron LI sctpPacketLengthRemaining -= sizeof(*dataHdrPtr);
602411677aeSAaron LI chunkLengthRemaining -= sizeof(*dataHdrPtr);
603411677aeSAaron LI payload_size = chunkLengthRemaining;
604411677aeSAaron LI if (payload_size == 0) {
605*ed775ee7SAntonio Huete Jimenez ND_PRINT("bogus chunk length %u]", chunkLength);
606411677aeSAaron LI return;
607411677aeSAaron LI }
608411677aeSAaron LI
60927bfbee1SPeter Avalos if (isforces) {
610411677aeSAaron LI forces_print(ndo, bp, payload_size);
611*ed775ee7SAntonio Huete Jimenez /* ndo_protocol reassignment after forces_print() call */
612*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "sctp";
613411677aeSAaron LI } else if (ndo->ndo_vflag >= 2) { /* if verbose output is specified */
61427bfbee1SPeter Avalos /* at the command line */
615411677aeSAaron LI switch (ppid) {
616411677aeSAaron LI case SCTP_PPID_M3UA :
617411677aeSAaron LI m3ua_print(ndo, bp, payload_size);
618*ed775ee7SAntonio Huete Jimenez /* ndo_protocol reassignment after m3ua_print() call */
619*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "sctp";
620411677aeSAaron LI break;
621411677aeSAaron LI default:
622*ed775ee7SAntonio Huete Jimenez ND_PRINT("[Payload");
623411677aeSAaron LI if (!ndo->ndo_suppress_default_print) {
624*ed775ee7SAntonio Huete Jimenez ND_PRINT(":");
625411677aeSAaron LI ND_DEFAULTPRINT(bp, payload_size);
62641c99275SPeter Avalos }
627*ed775ee7SAntonio Huete Jimenez ND_PRINT("]");
628411677aeSAaron LI break;
62941c99275SPeter Avalos }
630411677aeSAaron LI }
631411677aeSAaron LI bp += payload_size;
632411677aeSAaron LI sctpPacketLengthRemaining -= payload_size;
633411677aeSAaron LI chunkLengthRemaining -= payload_size;
63441c99275SPeter Avalos break;
63541c99275SPeter Avalos }
63641c99275SPeter Avalos case SCTP_INITIATION :
63741c99275SPeter Avalos {
63841c99275SPeter Avalos const struct sctpInitiation *init;
63941c99275SPeter Avalos
640411677aeSAaron LI if (chunkLengthRemaining < sizeof(*init)) {
641*ed775ee7SAntonio Huete Jimenez ND_PRINT("bogus chunk length %u]", chunkLength);
642411677aeSAaron LI return;
643411677aeSAaron LI }
644411677aeSAaron LI init=(const struct sctpInitiation*)bp;
645*ed775ee7SAntonio Huete Jimenez ND_PRINT("[init tag: %u] ", GET_BE_U_4(init->initTag));
646*ed775ee7SAntonio Huete Jimenez ND_PRINT("[rwnd: %u] ", GET_BE_U_4(init->rcvWindowCredit));
647*ed775ee7SAntonio Huete Jimenez ND_PRINT("[OS: %u] ", GET_BE_U_2(init->NumPreopenStreams));
648*ed775ee7SAntonio Huete Jimenez ND_PRINT("[MIS: %u] ", GET_BE_U_2(init->MaxInboundStreams));
649*ed775ee7SAntonio Huete Jimenez ND_PRINT("[init TSN: %u] ", GET_BE_U_4(init->initialTSN));
650411677aeSAaron LI bp += sizeof(*init);
651411677aeSAaron LI sctpPacketLengthRemaining -= sizeof(*init);
652411677aeSAaron LI chunkLengthRemaining -= sizeof(*init);
65341c99275SPeter Avalos
654411677aeSAaron LI #if 0 /* ALC you can add code for optional params here */
655411677aeSAaron LI if( chunkLengthRemaining != 0 )
656*ed775ee7SAntonio Huete Jimenez ND_PRINT(" @@@@@ UNFINISHED @@@@@@%s\n",
657*ed775ee7SAntonio Huete Jimenez "Optional params present, but not printed.");
65841c99275SPeter Avalos #endif
659411677aeSAaron LI bp += chunkLengthRemaining;
660411677aeSAaron LI sctpPacketLengthRemaining -= chunkLengthRemaining;
661411677aeSAaron LI chunkLengthRemaining = 0;
66241c99275SPeter Avalos break;
66341c99275SPeter Avalos }
66441c99275SPeter Avalos case SCTP_INITIATION_ACK :
66541c99275SPeter Avalos {
66641c99275SPeter Avalos const struct sctpInitiation *init;
66741c99275SPeter Avalos
668411677aeSAaron LI if (chunkLengthRemaining < sizeof(*init)) {
669*ed775ee7SAntonio Huete Jimenez ND_PRINT("bogus chunk length %u]", chunkLength);
670411677aeSAaron LI return;
671411677aeSAaron LI }
672411677aeSAaron LI init=(const struct sctpInitiation*)bp;
673*ed775ee7SAntonio Huete Jimenez ND_PRINT("[init tag: %u] ", GET_BE_U_4(init->initTag));
674*ed775ee7SAntonio Huete Jimenez ND_PRINT("[rwnd: %u] ", GET_BE_U_4(init->rcvWindowCredit));
675*ed775ee7SAntonio Huete Jimenez ND_PRINT("[OS: %u] ", GET_BE_U_2(init->NumPreopenStreams));
676*ed775ee7SAntonio Huete Jimenez ND_PRINT("[MIS: %u] ", GET_BE_U_2(init->MaxInboundStreams));
677*ed775ee7SAntonio Huete Jimenez ND_PRINT("[init TSN: %u] ", GET_BE_U_4(init->initialTSN));
678411677aeSAaron LI bp += sizeof(*init);
679411677aeSAaron LI sctpPacketLengthRemaining -= sizeof(*init);
680411677aeSAaron LI chunkLengthRemaining -= sizeof(*init);
68141c99275SPeter Avalos
682411677aeSAaron LI #if 0 /* ALC you can add code for optional params here */
683411677aeSAaron LI if( chunkLengthRemaining != 0 )
684*ed775ee7SAntonio Huete Jimenez ND_PRINT(" @@@@@ UNFINISHED @@@@@@%s\n",
685*ed775ee7SAntonio Huete Jimenez "Optional params present, but not printed.");
68641c99275SPeter Avalos #endif
687411677aeSAaron LI bp += chunkLengthRemaining;
688411677aeSAaron LI sctpPacketLengthRemaining -= chunkLengthRemaining;
689411677aeSAaron LI chunkLengthRemaining = 0;
69041c99275SPeter Avalos break;
69141c99275SPeter Avalos }
69241c99275SPeter Avalos case SCTP_SELECTIVE_ACK:
69341c99275SPeter Avalos {
69441c99275SPeter Avalos const struct sctpSelectiveAck *sack;
69541c99275SPeter Avalos const struct sctpSelectiveFrag *frag;
696*ed775ee7SAntonio Huete Jimenez u_int fragNo, tsnNo;
69741c99275SPeter Avalos const u_char *dupTSN;
69841c99275SPeter Avalos
699411677aeSAaron LI if (chunkLengthRemaining < sizeof(*sack)) {
700*ed775ee7SAntonio Huete Jimenez ND_PRINT("bogus chunk length %u]", chunkLength);
701411677aeSAaron LI return;
702411677aeSAaron LI }
703411677aeSAaron LI sack=(const struct sctpSelectiveAck*)bp;
704*ed775ee7SAntonio Huete Jimenez ND_PRINT("[cum ack %u] ", GET_BE_U_4(sack->highestConseqTSN));
705*ed775ee7SAntonio Huete Jimenez ND_PRINT("[a_rwnd %u] ", GET_BE_U_4(sack->updatedRwnd));
706*ed775ee7SAntonio Huete Jimenez ND_PRINT("[#gap acks %u] ", GET_BE_U_2(sack->numberOfdesc));
707*ed775ee7SAntonio Huete Jimenez ND_PRINT("[#dup tsns %u] ", GET_BE_U_2(sack->numDupTsns));
708411677aeSAaron LI bp += sizeof(*sack);
709411677aeSAaron LI sctpPacketLengthRemaining -= sizeof(*sack);
710411677aeSAaron LI chunkLengthRemaining -= sizeof(*sack);
71141c99275SPeter Avalos
71241c99275SPeter Avalos
71341c99275SPeter Avalos /* print gaps */
714411677aeSAaron LI for (fragNo=0;
715*ed775ee7SAntonio Huete Jimenez chunkLengthRemaining != 0 && fragNo < GET_BE_U_2(sack->numberOfdesc);
716411677aeSAaron LI bp += sizeof(*frag), sctpPacketLengthRemaining -= sizeof(*frag), chunkLengthRemaining -= sizeof(*frag), fragNo++) {
717411677aeSAaron LI if (chunkLengthRemaining < sizeof(*frag)) {
718*ed775ee7SAntonio Huete Jimenez ND_PRINT("bogus chunk length %u]", chunkLength);
71941c99275SPeter Avalos return;
72041c99275SPeter Avalos }
721411677aeSAaron LI frag = (const struct sctpSelectiveFrag *)bp;
722*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t\t[gap ack block #%u: start = %u, end = %u] ",
723411677aeSAaron LI fragNo+1,
724*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sack->highestConseqTSN) + GET_BE_U_2(frag->fragmentStart),
725*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sack->highestConseqTSN) + GET_BE_U_2(frag->fragmentEnd));
726411677aeSAaron LI }
72741c99275SPeter Avalos
728411677aeSAaron LI /* print duplicate TSNs */
729411677aeSAaron LI for (tsnNo=0;
730*ed775ee7SAntonio Huete Jimenez chunkLengthRemaining != 0 && tsnNo<GET_BE_U_2(sack->numDupTsns);
731411677aeSAaron LI bp += 4, sctpPacketLengthRemaining -= 4, chunkLengthRemaining -= 4, tsnNo++) {
732411677aeSAaron LI if (chunkLengthRemaining < 4) {
733*ed775ee7SAntonio Huete Jimenez ND_PRINT("bogus chunk length %u]", chunkLength);
734411677aeSAaron LI return;
735411677aeSAaron LI }
736411677aeSAaron LI dupTSN = (const u_char *)bp;
737*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
738*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(dupTSN));
739411677aeSAaron LI }
740411677aeSAaron LI break;
741411677aeSAaron LI }
742411677aeSAaron LI default :
743411677aeSAaron LI {
744411677aeSAaron LI bp += chunkLengthRemaining;
745411677aeSAaron LI sctpPacketLengthRemaining -= chunkLengthRemaining;
746411677aeSAaron LI chunkLengthRemaining = 0;
747411677aeSAaron LI break;
748411677aeSAaron LI }
749411677aeSAaron LI }
750411677aeSAaron LI
751411677aeSAaron LI /*
752411677aeSAaron LI * Any extra stuff at the end of the chunk?
753411677aeSAaron LI * XXX - report this?
754411677aeSAaron LI */
755411677aeSAaron LI bp += chunkLengthRemaining;
756411677aeSAaron LI sctpPacketLengthRemaining -= chunkLengthRemaining;
757411677aeSAaron LI
758411677aeSAaron LI if (ndo->ndo_vflag < 2)
75941c99275SPeter Avalos sep = ", (";
760411677aeSAaron LI
761411677aeSAaron LI if (align != 0) {
762411677aeSAaron LI /*
763411677aeSAaron LI * Fail if the alignment padding isn't in the captured data.
764411677aeSAaron LI * Otherwise, skip it.
765411677aeSAaron LI */
766*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(bp, align);
767411677aeSAaron LI bp += align;
768411677aeSAaron LI sctpPacketLengthRemaining -= align;
769411677aeSAaron LI }
77041c99275SPeter Avalos }
77141c99275SPeter Avalos return;
77241c99275SPeter Avalos
77341c99275SPeter Avalos trunc:
774*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
77541c99275SPeter Avalos }
776