1*b636d99dSDavid van Moolenbroek /*
2*b636d99dSDavid van Moolenbroek * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware
3*b636d99dSDavid van Moolenbroek *
4*b636d99dSDavid van Moolenbroek * Jerry Heinz <gheinz@astro.temple.edu>
5*b636d99dSDavid van Moolenbroek * John Fiore <jfiore@joda.cis.temple.edu>
6*b636d99dSDavid van Moolenbroek * Armando L. Caro Jr. <acaro@cis.udel.edu>
7*b636d99dSDavid van Moolenbroek *
8*b636d99dSDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
9*b636d99dSDavid van Moolenbroek * modification, are permitted provided that the following conditions
10*b636d99dSDavid van Moolenbroek * are met:
11*b636d99dSDavid van Moolenbroek *
12*b636d99dSDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
13*b636d99dSDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
14*b636d99dSDavid van Moolenbroek *
15*b636d99dSDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
16*b636d99dSDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
17*b636d99dSDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
18*b636d99dSDavid van Moolenbroek *
19*b636d99dSDavid van Moolenbroek * 3. Neither the name of the University nor of the Laboratory may be used
20*b636d99dSDavid van Moolenbroek * to endorse or promote products derived from this software without
21*b636d99dSDavid van Moolenbroek * specific prior written permission.
22*b636d99dSDavid van Moolenbroek *
23*b636d99dSDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24*b636d99dSDavid van Moolenbroek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25*b636d99dSDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26*b636d99dSDavid van Moolenbroek * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27*b636d99dSDavid van Moolenbroek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28*b636d99dSDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29*b636d99dSDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30*b636d99dSDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31*b636d99dSDavid van Moolenbroek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32*b636d99dSDavid van Moolenbroek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33*b636d99dSDavid van Moolenbroek * SUCH DAMAGE.
34*b636d99dSDavid van Moolenbroek */
35*b636d99dSDavid van Moolenbroek
36*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
37*b636d99dSDavid van Moolenbroek #ifndef lint
38*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-sctp.c,v 1.6 2014/11/20 03:05:03 christos Exp $");
39*b636d99dSDavid van Moolenbroek #endif
40*b636d99dSDavid van Moolenbroek
41*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
42*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
43*b636d99dSDavid van Moolenbroek #include "config.h"
44*b636d99dSDavid van Moolenbroek #endif
45*b636d99dSDavid van Moolenbroek
46*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
47*b636d99dSDavid van Moolenbroek
48*b636d99dSDavid van Moolenbroek #include "interface.h"
49*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
50*b636d99dSDavid van Moolenbroek #include "extract.h" /* must come after interface.h */
51*b636d99dSDavid van Moolenbroek #include "ip.h"
52*b636d99dSDavid van Moolenbroek #ifdef INET6
53*b636d99dSDavid van Moolenbroek #include "ip6.h"
54*b636d99dSDavid van Moolenbroek #endif
55*b636d99dSDavid van Moolenbroek
56*b636d99dSDavid van Moolenbroek /* Definitions from:
57*b636d99dSDavid van Moolenbroek *
58*b636d99dSDavid van Moolenbroek * SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola
59*b636d99dSDavid van Moolenbroek *
60*b636d99dSDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
61*b636d99dSDavid van Moolenbroek * modification, are permitted provided that the following conditions
62*b636d99dSDavid van Moolenbroek * are met:
63*b636d99dSDavid van Moolenbroek *
64*b636d99dSDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
65*b636d99dSDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
66*b636d99dSDavid van Moolenbroek *
67*b636d99dSDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
68*b636d99dSDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
69*b636d99dSDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
70*b636d99dSDavid van Moolenbroek *
71*b636d99dSDavid van Moolenbroek * 3. Neither the name of Cisco nor of Motorola may be used
72*b636d99dSDavid van Moolenbroek * to endorse or promote products derived from this software without
73*b636d99dSDavid van Moolenbroek * specific prior written permission.
74*b636d99dSDavid van Moolenbroek *
75*b636d99dSDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
76*b636d99dSDavid van Moolenbroek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
77*b636d99dSDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
78*b636d99dSDavid van Moolenbroek * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
79*b636d99dSDavid van Moolenbroek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
80*b636d99dSDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
81*b636d99dSDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
82*b636d99dSDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
83*b636d99dSDavid van Moolenbroek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
84*b636d99dSDavid van Moolenbroek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85*b636d99dSDavid van Moolenbroek * SUCH DAMAGE.
86*b636d99dSDavid van Moolenbroek *
87*b636d99dSDavid van Moolenbroek * This file is part of the SCTP reference Implementation
88*b636d99dSDavid van Moolenbroek *
89*b636d99dSDavid van Moolenbroek *
90*b636d99dSDavid van Moolenbroek * Please send any bug reports or fixes you make to one of the following email
91*b636d99dSDavid van Moolenbroek * addresses:
92*b636d99dSDavid van Moolenbroek *
93*b636d99dSDavid van Moolenbroek * rstewar1@email.mot.com
94*b636d99dSDavid van Moolenbroek * kmorneau@cisco.com
95*b636d99dSDavid van Moolenbroek * qxie1@email.mot.com
96*b636d99dSDavid van Moolenbroek *
97*b636d99dSDavid van Moolenbroek * Any bugs reported given to us we will try to fix... any fixes shared will
98*b636d99dSDavid van Moolenbroek * be incorperated into the next SCTP release.
99*b636d99dSDavid van Moolenbroek */
100*b636d99dSDavid van Moolenbroek
101*b636d99dSDavid van Moolenbroek /* The valid defines for all message
102*b636d99dSDavid van Moolenbroek * types know to SCTP. 0 is reserved
103*b636d99dSDavid van Moolenbroek */
104*b636d99dSDavid van Moolenbroek #define SCTP_DATA 0x00
105*b636d99dSDavid van Moolenbroek #define SCTP_INITIATION 0x01
106*b636d99dSDavid van Moolenbroek #define SCTP_INITIATION_ACK 0x02
107*b636d99dSDavid van Moolenbroek #define SCTP_SELECTIVE_ACK 0x03
108*b636d99dSDavid van Moolenbroek #define SCTP_HEARTBEAT_REQUEST 0x04
109*b636d99dSDavid van Moolenbroek #define SCTP_HEARTBEAT_ACK 0x05
110*b636d99dSDavid van Moolenbroek #define SCTP_ABORT_ASSOCIATION 0x06
111*b636d99dSDavid van Moolenbroek #define SCTP_SHUTDOWN 0x07
112*b636d99dSDavid van Moolenbroek #define SCTP_SHUTDOWN_ACK 0x08
113*b636d99dSDavid van Moolenbroek #define SCTP_OPERATION_ERR 0x09
114*b636d99dSDavid van Moolenbroek #define SCTP_COOKIE_ECHO 0x0a
115*b636d99dSDavid van Moolenbroek #define SCTP_COOKIE_ACK 0x0b
116*b636d99dSDavid van Moolenbroek #define SCTP_ECN_ECHO 0x0c
117*b636d99dSDavid van Moolenbroek #define SCTP_ECN_CWR 0x0d
118*b636d99dSDavid van Moolenbroek #define SCTP_SHUTDOWN_COMPLETE 0x0e
119*b636d99dSDavid van Moolenbroek #define SCTP_FORWARD_CUM_TSN 0xc0
120*b636d99dSDavid van Moolenbroek #define SCTP_RELIABLE_CNTL 0xc1
121*b636d99dSDavid van Moolenbroek #define SCTP_RELIABLE_CNTL_ACK 0xc2
122*b636d99dSDavid van Moolenbroek
123*b636d99dSDavid van Moolenbroek static const struct tok sctp_chunkid_str[] = {
124*b636d99dSDavid van Moolenbroek { SCTP_DATA, "DATA" },
125*b636d99dSDavid van Moolenbroek { SCTP_INITIATION, "INIT" },
126*b636d99dSDavid van Moolenbroek { SCTP_INITIATION_ACK, "INIT ACK" },
127*b636d99dSDavid van Moolenbroek { SCTP_SELECTIVE_ACK, "SACK" },
128*b636d99dSDavid van Moolenbroek { SCTP_HEARTBEAT_REQUEST, "HB REQ" },
129*b636d99dSDavid van Moolenbroek { SCTP_HEARTBEAT_ACK, "HB ACK" },
130*b636d99dSDavid van Moolenbroek { SCTP_ABORT_ASSOCIATION, "ABORT" },
131*b636d99dSDavid van Moolenbroek { SCTP_SHUTDOWN, "SHUTDOWN" },
132*b636d99dSDavid van Moolenbroek { SCTP_SHUTDOWN_ACK, "SHUTDOWN ACK" },
133*b636d99dSDavid van Moolenbroek { SCTP_OPERATION_ERR, "OP ERR" },
134*b636d99dSDavid van Moolenbroek { SCTP_COOKIE_ECHO, "COOKIE ECHO" },
135*b636d99dSDavid van Moolenbroek { SCTP_COOKIE_ACK, "COOKIE ACK" },
136*b636d99dSDavid van Moolenbroek { SCTP_ECN_ECHO, "ECN ECHO" },
137*b636d99dSDavid van Moolenbroek { SCTP_ECN_CWR, "ECN CWR" },
138*b636d99dSDavid van Moolenbroek { SCTP_SHUTDOWN_COMPLETE, "SHUTDOWN COMPLETE" },
139*b636d99dSDavid van Moolenbroek { SCTP_FORWARD_CUM_TSN, "FOR CUM TSN" },
140*b636d99dSDavid van Moolenbroek { SCTP_RELIABLE_CNTL, "REL CTRL" },
141*b636d99dSDavid van Moolenbroek { SCTP_RELIABLE_CNTL_ACK, "REL CTRL ACK" },
142*b636d99dSDavid van Moolenbroek { 0, NULL }
143*b636d99dSDavid van Moolenbroek };
144*b636d99dSDavid van Moolenbroek
145*b636d99dSDavid van Moolenbroek /* Data Chuck Specific Flags */
146*b636d99dSDavid van Moolenbroek #define SCTP_DATA_FRAG_MASK 0x03
147*b636d99dSDavid van Moolenbroek #define SCTP_DATA_MIDDLE_FRAG 0x00
148*b636d99dSDavid van Moolenbroek #define SCTP_DATA_LAST_FRAG 0x01
149*b636d99dSDavid van Moolenbroek #define SCTP_DATA_FIRST_FRAG 0x02
150*b636d99dSDavid van Moolenbroek #define SCTP_DATA_NOT_FRAG 0x03
151*b636d99dSDavid van Moolenbroek #define SCTP_DATA_UNORDERED 0x04
152*b636d99dSDavid van Moolenbroek
153*b636d99dSDavid van Moolenbroek #define SCTP_ADDRMAX 60
154*b636d99dSDavid van Moolenbroek
155*b636d99dSDavid van Moolenbroek #define CHAN_HP 6704
156*b636d99dSDavid van Moolenbroek #define CHAN_MP 6705
157*b636d99dSDavid van Moolenbroek #define CHAN_LP 6706
158*b636d99dSDavid van Moolenbroek
159*b636d99dSDavid van Moolenbroek /* the sctp common header */
160*b636d99dSDavid van Moolenbroek
161*b636d99dSDavid van Moolenbroek struct sctpHeader{
162*b636d99dSDavid van Moolenbroek uint16_t source;
163*b636d99dSDavid van Moolenbroek uint16_t destination;
164*b636d99dSDavid van Moolenbroek uint32_t verificationTag;
165*b636d99dSDavid van Moolenbroek uint32_t adler32;
166*b636d99dSDavid van Moolenbroek };
167*b636d99dSDavid van Moolenbroek
168*b636d99dSDavid van Moolenbroek /* various descriptor parsers */
169*b636d99dSDavid van Moolenbroek
170*b636d99dSDavid van Moolenbroek struct sctpChunkDesc{
171*b636d99dSDavid van Moolenbroek uint8_t chunkID;
172*b636d99dSDavid van Moolenbroek uint8_t chunkFlg;
173*b636d99dSDavid van Moolenbroek uint16_t chunkLength;
174*b636d99dSDavid van Moolenbroek };
175*b636d99dSDavid van Moolenbroek
176*b636d99dSDavid van Moolenbroek struct sctpParamDesc{
177*b636d99dSDavid van Moolenbroek uint16_t paramType;
178*b636d99dSDavid van Moolenbroek uint16_t paramLength;
179*b636d99dSDavid van Moolenbroek };
180*b636d99dSDavid van Moolenbroek
181*b636d99dSDavid van Moolenbroek
182*b636d99dSDavid van Moolenbroek struct sctpRelChunkDesc{
183*b636d99dSDavid van Moolenbroek struct sctpChunkDesc chk;
184*b636d99dSDavid van Moolenbroek uint32_t serialNumber;
185*b636d99dSDavid van Moolenbroek };
186*b636d99dSDavid van Moolenbroek
187*b636d99dSDavid van Moolenbroek struct sctpVendorSpecificParam {
188*b636d99dSDavid van Moolenbroek struct sctpParamDesc p; /* type must be 0xfffe */
189*b636d99dSDavid van Moolenbroek uint32_t vendorId; /* vendor ID from RFC 1700 */
190*b636d99dSDavid van Moolenbroek uint16_t vendorSpecificType;
191*b636d99dSDavid van Moolenbroek uint16_t vendorSpecificLen;
192*b636d99dSDavid van Moolenbroek };
193*b636d99dSDavid van Moolenbroek
194*b636d99dSDavid van Moolenbroek
195*b636d99dSDavid van Moolenbroek /* Structures for the control parts */
196*b636d99dSDavid van Moolenbroek
197*b636d99dSDavid van Moolenbroek
198*b636d99dSDavid van Moolenbroek
199*b636d99dSDavid van Moolenbroek /* Sctp association init request/ack */
200*b636d99dSDavid van Moolenbroek
201*b636d99dSDavid van Moolenbroek /* this is used for init ack, too */
202*b636d99dSDavid van Moolenbroek struct sctpInitiation{
203*b636d99dSDavid van Moolenbroek uint32_t initTag; /* tag of mine */
204*b636d99dSDavid van Moolenbroek uint32_t rcvWindowCredit; /* rwnd */
205*b636d99dSDavid van Moolenbroek uint16_t NumPreopenStreams; /* OS */
206*b636d99dSDavid van Moolenbroek uint16_t MaxInboundStreams; /* MIS */
207*b636d99dSDavid van Moolenbroek uint32_t initialTSN;
208*b636d99dSDavid van Moolenbroek /* optional param's follow in sctpParamDesc form */
209*b636d99dSDavid van Moolenbroek };
210*b636d99dSDavid van Moolenbroek
211*b636d99dSDavid van Moolenbroek struct sctpV4IpAddress{
212*b636d99dSDavid van Moolenbroek struct sctpParamDesc p; /* type is set to SCTP_IPV4_PARAM_TYPE, len=10 */
213*b636d99dSDavid van Moolenbroek uint32_t ipAddress;
214*b636d99dSDavid van Moolenbroek };
215*b636d99dSDavid van Moolenbroek
216*b636d99dSDavid van Moolenbroek
217*b636d99dSDavid van Moolenbroek struct sctpV6IpAddress{
218*b636d99dSDavid van Moolenbroek struct sctpParamDesc p; /* type is set to SCTP_IPV6_PARAM_TYPE, len=22 */
219*b636d99dSDavid van Moolenbroek uint8_t ipAddress[16];
220*b636d99dSDavid van Moolenbroek };
221*b636d99dSDavid van Moolenbroek
222*b636d99dSDavid van Moolenbroek struct sctpDNSName{
223*b636d99dSDavid van Moolenbroek struct sctpParamDesc param;
224*b636d99dSDavid van Moolenbroek uint8_t name[1];
225*b636d99dSDavid van Moolenbroek };
226*b636d99dSDavid van Moolenbroek
227*b636d99dSDavid van Moolenbroek
228*b636d99dSDavid van Moolenbroek struct sctpCookiePreserve{
229*b636d99dSDavid van Moolenbroek struct sctpParamDesc p; /* type is set to SCTP_COOKIE_PRESERVE, len=8 */
230*b636d99dSDavid van Moolenbroek uint32_t extraTime;
231*b636d99dSDavid van Moolenbroek };
232*b636d99dSDavid van Moolenbroek
233*b636d99dSDavid van Moolenbroek
234*b636d99dSDavid van Moolenbroek struct sctpTimeStamp{
235*b636d99dSDavid van Moolenbroek uint32_t ts_sec;
236*b636d99dSDavid van Moolenbroek uint32_t ts_usec;
237*b636d99dSDavid van Moolenbroek };
238*b636d99dSDavid van Moolenbroek
239*b636d99dSDavid van Moolenbroek /* wire structure of my cookie */
240*b636d99dSDavid van Moolenbroek struct cookieMessage{
241*b636d99dSDavid van Moolenbroek uint32_t TieTag_curTag; /* copied from assoc if present */
242*b636d99dSDavid van Moolenbroek uint32_t TieTag_hisTag; /* copied from assoc if present */
243*b636d99dSDavid van Moolenbroek int32_t cookieLife; /* life I will award this cookie */
244*b636d99dSDavid van Moolenbroek struct sctpTimeStamp timeEnteringState; /* the time I built cookie */
245*b636d99dSDavid van Moolenbroek struct sctpInitiation initAckISent; /* the INIT-ACK that I sent to my peer */
246*b636d99dSDavid van Moolenbroek uint32_t addressWhereISent[4]; /* I make this 4 ints so I get 128bits for future */
247*b636d99dSDavid van Moolenbroek int32_t addrtype; /* address type */
248*b636d99dSDavid van Moolenbroek uint16_t locScope; /* V6 local scope flag */
249*b636d99dSDavid van Moolenbroek uint16_t siteScope; /* V6 site scope flag */
250*b636d99dSDavid van Moolenbroek /* at the end is tacked on the INIT chunk sent in
251*b636d99dSDavid van Moolenbroek * its entirety and of course our
252*b636d99dSDavid van Moolenbroek * signature.
253*b636d99dSDavid van Moolenbroek */
254*b636d99dSDavid van Moolenbroek };
255*b636d99dSDavid van Moolenbroek
256*b636d99dSDavid van Moolenbroek
257*b636d99dSDavid van Moolenbroek /* this guy is for use when
258*b636d99dSDavid van Moolenbroek * I have a initiate message gloming the
259*b636d99dSDavid van Moolenbroek * things together.
260*b636d99dSDavid van Moolenbroek
261*b636d99dSDavid van Moolenbroek */
262*b636d99dSDavid van Moolenbroek struct sctpUnifiedInit{
263*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
264*b636d99dSDavid van Moolenbroek struct sctpInitiation initm;
265*b636d99dSDavid van Moolenbroek };
266*b636d99dSDavid van Moolenbroek
267*b636d99dSDavid van Moolenbroek struct sctpSendableInit{
268*b636d99dSDavid van Moolenbroek struct sctpHeader mh;
269*b636d99dSDavid van Moolenbroek struct sctpUnifiedInit msg;
270*b636d99dSDavid van Moolenbroek };
271*b636d99dSDavid van Moolenbroek
272*b636d99dSDavid van Moolenbroek
273*b636d99dSDavid van Moolenbroek /* Selective Acknowledgement
274*b636d99dSDavid van Moolenbroek * has the following structure with
275*b636d99dSDavid van Moolenbroek * a optional ammount of trailing int's
276*b636d99dSDavid van Moolenbroek * on the last part (based on the numberOfDesc
277*b636d99dSDavid van Moolenbroek * field).
278*b636d99dSDavid van Moolenbroek */
279*b636d99dSDavid van Moolenbroek
280*b636d99dSDavid van Moolenbroek struct sctpSelectiveAck{
281*b636d99dSDavid van Moolenbroek uint32_t highestConseqTSN;
282*b636d99dSDavid van Moolenbroek uint32_t updatedRwnd;
283*b636d99dSDavid van Moolenbroek uint16_t numberOfdesc;
284*b636d99dSDavid van Moolenbroek uint16_t numDupTsns;
285*b636d99dSDavid van Moolenbroek };
286*b636d99dSDavid van Moolenbroek
287*b636d99dSDavid van Moolenbroek struct sctpSelectiveFrag{
288*b636d99dSDavid van Moolenbroek uint16_t fragmentStart;
289*b636d99dSDavid van Moolenbroek uint16_t fragmentEnd;
290*b636d99dSDavid van Moolenbroek };
291*b636d99dSDavid van Moolenbroek
292*b636d99dSDavid van Moolenbroek
293*b636d99dSDavid van Moolenbroek struct sctpUnifiedSack{
294*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
295*b636d99dSDavid van Moolenbroek struct sctpSelectiveAck sack;
296*b636d99dSDavid van Moolenbroek };
297*b636d99dSDavid van Moolenbroek
298*b636d99dSDavid van Moolenbroek /* for both RTT request/response the
299*b636d99dSDavid van Moolenbroek * following is sent
300*b636d99dSDavid van Moolenbroek */
301*b636d99dSDavid van Moolenbroek
302*b636d99dSDavid van Moolenbroek struct sctpHBrequest {
303*b636d99dSDavid van Moolenbroek uint32_t time_value_1;
304*b636d99dSDavid van Moolenbroek uint32_t time_value_2;
305*b636d99dSDavid van Moolenbroek };
306*b636d99dSDavid van Moolenbroek
307*b636d99dSDavid van Moolenbroek /* here is what I read and respond with to. */
308*b636d99dSDavid van Moolenbroek struct sctpHBunified{
309*b636d99dSDavid van Moolenbroek struct sctpChunkDesc hdr;
310*b636d99dSDavid van Moolenbroek struct sctpParamDesc hb;
311*b636d99dSDavid van Moolenbroek };
312*b636d99dSDavid van Moolenbroek
313*b636d99dSDavid van Moolenbroek
314*b636d99dSDavid van Moolenbroek /* here is what I send */
315*b636d99dSDavid van Moolenbroek struct sctpHBsender{
316*b636d99dSDavid van Moolenbroek struct sctpChunkDesc hdr;
317*b636d99dSDavid van Moolenbroek struct sctpParamDesc hb;
318*b636d99dSDavid van Moolenbroek struct sctpHBrequest rtt;
319*b636d99dSDavid van Moolenbroek int8_t addrFmt[SCTP_ADDRMAX];
320*b636d99dSDavid van Moolenbroek uint16_t userreq;
321*b636d99dSDavid van Moolenbroek };
322*b636d99dSDavid van Moolenbroek
323*b636d99dSDavid van Moolenbroek
324*b636d99dSDavid van Moolenbroek
325*b636d99dSDavid van Moolenbroek /* for the abort and shutdown ACK
326*b636d99dSDavid van Moolenbroek * we must carry the init tag in the common header. Just the
327*b636d99dSDavid van Moolenbroek * common header is all that is needed with a chunk descriptor.
328*b636d99dSDavid van Moolenbroek */
329*b636d99dSDavid van Moolenbroek struct sctpUnifiedAbort{
330*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
331*b636d99dSDavid van Moolenbroek };
332*b636d99dSDavid van Moolenbroek
333*b636d99dSDavid van Moolenbroek struct sctpUnifiedAbortLight{
334*b636d99dSDavid van Moolenbroek struct sctpHeader mh;
335*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
336*b636d99dSDavid van Moolenbroek };
337*b636d99dSDavid van Moolenbroek
338*b636d99dSDavid van Moolenbroek struct sctpUnifiedAbortHeavy{
339*b636d99dSDavid van Moolenbroek struct sctpHeader mh;
340*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
341*b636d99dSDavid van Moolenbroek uint16_t causeCode;
342*b636d99dSDavid van Moolenbroek uint16_t causeLen;
343*b636d99dSDavid van Moolenbroek };
344*b636d99dSDavid van Moolenbroek
345*b636d99dSDavid van Moolenbroek /* For the graceful shutdown we must carry
346*b636d99dSDavid van Moolenbroek * the tag (in common header) and the highest consequitive acking value
347*b636d99dSDavid van Moolenbroek */
348*b636d99dSDavid van Moolenbroek struct sctpShutdown {
349*b636d99dSDavid van Moolenbroek uint32_t TSN_Seen;
350*b636d99dSDavid van Moolenbroek };
351*b636d99dSDavid van Moolenbroek
352*b636d99dSDavid van Moolenbroek struct sctpUnifiedShutdown{
353*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
354*b636d99dSDavid van Moolenbroek struct sctpShutdown shut;
355*b636d99dSDavid van Moolenbroek };
356*b636d99dSDavid van Moolenbroek
357*b636d99dSDavid van Moolenbroek /* in the unified message we add the trailing
358*b636d99dSDavid van Moolenbroek * stream id since it is the only message
359*b636d99dSDavid van Moolenbroek * that is defined as a operation error.
360*b636d99dSDavid van Moolenbroek */
361*b636d99dSDavid van Moolenbroek struct sctpOpErrorCause{
362*b636d99dSDavid van Moolenbroek uint16_t cause;
363*b636d99dSDavid van Moolenbroek uint16_t causeLen;
364*b636d99dSDavid van Moolenbroek };
365*b636d99dSDavid van Moolenbroek
366*b636d99dSDavid van Moolenbroek struct sctpUnifiedOpError{
367*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
368*b636d99dSDavid van Moolenbroek struct sctpOpErrorCause c;
369*b636d99dSDavid van Moolenbroek };
370*b636d99dSDavid van Moolenbroek
371*b636d99dSDavid van Moolenbroek struct sctpUnifiedStreamError{
372*b636d99dSDavid van Moolenbroek struct sctpHeader mh;
373*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
374*b636d99dSDavid van Moolenbroek struct sctpOpErrorCause c;
375*b636d99dSDavid van Moolenbroek uint16_t strmNum;
376*b636d99dSDavid van Moolenbroek uint16_t reserved;
377*b636d99dSDavid van Moolenbroek };
378*b636d99dSDavid van Moolenbroek
379*b636d99dSDavid van Moolenbroek struct staleCookieMsg{
380*b636d99dSDavid van Moolenbroek struct sctpHeader mh;
381*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
382*b636d99dSDavid van Moolenbroek struct sctpOpErrorCause c;
383*b636d99dSDavid van Moolenbroek uint32_t moretime;
384*b636d99dSDavid van Moolenbroek };
385*b636d99dSDavid van Moolenbroek
386*b636d99dSDavid van Moolenbroek /* the following is used in all sends
387*b636d99dSDavid van Moolenbroek * where nothing is needed except the
388*b636d99dSDavid van Moolenbroek * chunk/type i.e. shutdownAck Abort */
389*b636d99dSDavid van Moolenbroek
390*b636d99dSDavid van Moolenbroek struct sctpUnifiedSingleMsg{
391*b636d99dSDavid van Moolenbroek struct sctpHeader mh;
392*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
393*b636d99dSDavid van Moolenbroek };
394*b636d99dSDavid van Moolenbroek
395*b636d99dSDavid van Moolenbroek struct sctpDataPart{
396*b636d99dSDavid van Moolenbroek uint32_t TSN;
397*b636d99dSDavid van Moolenbroek uint16_t streamId;
398*b636d99dSDavid van Moolenbroek uint16_t sequence;
399*b636d99dSDavid van Moolenbroek uint32_t payloadtype;
400*b636d99dSDavid van Moolenbroek };
401*b636d99dSDavid van Moolenbroek
402*b636d99dSDavid van Moolenbroek struct sctpUnifiedDatagram{
403*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
404*b636d99dSDavid van Moolenbroek struct sctpDataPart dp;
405*b636d99dSDavid van Moolenbroek };
406*b636d99dSDavid van Moolenbroek
407*b636d99dSDavid van Moolenbroek struct sctpECN_echo{
408*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
409*b636d99dSDavid van Moolenbroek uint32_t Lowest_TSN;
410*b636d99dSDavid van Moolenbroek };
411*b636d99dSDavid van Moolenbroek
412*b636d99dSDavid van Moolenbroek
413*b636d99dSDavid van Moolenbroek struct sctpCWR{
414*b636d99dSDavid van Moolenbroek struct sctpChunkDesc uh;
415*b636d99dSDavid van Moolenbroek uint32_t TSN_reduced_at;
416*b636d99dSDavid van Moolenbroek };
417*b636d99dSDavid van Moolenbroek
418*b636d99dSDavid van Moolenbroek static const struct tok ForCES_channels[] = {
419*b636d99dSDavid van Moolenbroek { CHAN_HP, "ForCES HP" },
420*b636d99dSDavid van Moolenbroek { CHAN_MP, "ForCES MP" },
421*b636d99dSDavid van Moolenbroek { CHAN_LP, "ForCES LP" },
422*b636d99dSDavid van Moolenbroek { 0, NULL }
423*b636d99dSDavid van Moolenbroek };
424*b636d99dSDavid van Moolenbroek
425*b636d99dSDavid van Moolenbroek /* data chunk's payload protocol identifiers */
426*b636d99dSDavid van Moolenbroek
427*b636d99dSDavid van Moolenbroek #define SCTP_PPID_IUA 1
428*b636d99dSDavid van Moolenbroek #define SCTP_PPID_M2UA 2
429*b636d99dSDavid van Moolenbroek #define SCTP_PPID_M3UA 3
430*b636d99dSDavid van Moolenbroek #define SCTP_PPID_SUA 4
431*b636d99dSDavid van Moolenbroek #define SCTP_PPID_M2PA 5
432*b636d99dSDavid van Moolenbroek #define SCTP_PPID_V5UA 6
433*b636d99dSDavid van Moolenbroek #define SCTP_PPID_H248 7
434*b636d99dSDavid van Moolenbroek #define SCTP_PPID_BICC 8
435*b636d99dSDavid van Moolenbroek #define SCTP_PPID_TALI 9
436*b636d99dSDavid van Moolenbroek #define SCTP_PPID_DUA 10
437*b636d99dSDavid van Moolenbroek #define SCTP_PPID_ASAP 11
438*b636d99dSDavid van Moolenbroek #define SCTP_PPID_ENRP 12
439*b636d99dSDavid van Moolenbroek #define SCTP_PPID_H323 13
440*b636d99dSDavid van Moolenbroek #define SCTP_PPID_QIPC 14
441*b636d99dSDavid van Moolenbroek #define SCTP_PPID_SIMCO 15
442*b636d99dSDavid van Moolenbroek #define SCTP_PPID_DDPSC 16
443*b636d99dSDavid van Moolenbroek #define SCTP_PPID_DDPSSC 17
444*b636d99dSDavid van Moolenbroek #define SCTP_PPID_S1AP 18
445*b636d99dSDavid van Moolenbroek #define SCTP_PPID_RUA 19
446*b636d99dSDavid van Moolenbroek #define SCTP_PPID_HNBAP 20
447*b636d99dSDavid van Moolenbroek #define SCTP_PPID_FORCES_HP 21
448*b636d99dSDavid van Moolenbroek #define SCTP_PPID_FORCES_MP 22
449*b636d99dSDavid van Moolenbroek #define SCTP_PPID_FORCES_LP 23
450*b636d99dSDavid van Moolenbroek #define SCTP_PPID_SBC_AP 24
451*b636d99dSDavid van Moolenbroek #define SCTP_PPID_NBAP 25
452*b636d99dSDavid van Moolenbroek /* 26 */
453*b636d99dSDavid van Moolenbroek #define SCTP_PPID_X2AP 27
454*b636d99dSDavid van Moolenbroek
455*b636d99dSDavid van Moolenbroek static const struct tok PayloadProto_idents[] = {
456*b636d99dSDavid van Moolenbroek { SCTP_PPID_IUA, "ISDN Q.921" },
457*b636d99dSDavid van Moolenbroek { SCTP_PPID_M2UA, "M2UA" },
458*b636d99dSDavid van Moolenbroek { SCTP_PPID_M3UA, "M3UA" },
459*b636d99dSDavid van Moolenbroek { SCTP_PPID_SUA, "SUA" },
460*b636d99dSDavid van Moolenbroek { SCTP_PPID_M2PA, "M2PA" },
461*b636d99dSDavid van Moolenbroek { SCTP_PPID_V5UA, "V5.2" },
462*b636d99dSDavid van Moolenbroek { SCTP_PPID_H248, "H.248" },
463*b636d99dSDavid van Moolenbroek { SCTP_PPID_BICC, "BICC" },
464*b636d99dSDavid van Moolenbroek { SCTP_PPID_TALI, "TALI" },
465*b636d99dSDavid van Moolenbroek { SCTP_PPID_DUA, "DUA" },
466*b636d99dSDavid van Moolenbroek { SCTP_PPID_ASAP, "ASAP" },
467*b636d99dSDavid van Moolenbroek { SCTP_PPID_ENRP, "ENRP" },
468*b636d99dSDavid van Moolenbroek { SCTP_PPID_H323, "H.323" },
469*b636d99dSDavid van Moolenbroek { SCTP_PPID_QIPC, "Q.IPC" },
470*b636d99dSDavid van Moolenbroek { SCTP_PPID_SIMCO, "SIMCO" },
471*b636d99dSDavid van Moolenbroek { SCTP_PPID_DDPSC, "DDPSC" },
472*b636d99dSDavid van Moolenbroek { SCTP_PPID_DDPSSC, "DDPSSC" },
473*b636d99dSDavid van Moolenbroek { SCTP_PPID_S1AP, "S1AP" },
474*b636d99dSDavid van Moolenbroek { SCTP_PPID_RUA, "RUA" },
475*b636d99dSDavid van Moolenbroek { SCTP_PPID_HNBAP, "HNBAP" },
476*b636d99dSDavid van Moolenbroek { SCTP_PPID_FORCES_HP, "ForCES HP" },
477*b636d99dSDavid van Moolenbroek { SCTP_PPID_FORCES_MP, "ForCES MP" },
478*b636d99dSDavid van Moolenbroek { SCTP_PPID_FORCES_LP, "ForCES LP" },
479*b636d99dSDavid van Moolenbroek { SCTP_PPID_SBC_AP, "SBc-AP" },
480*b636d99dSDavid van Moolenbroek { SCTP_PPID_NBAP, "NBAP" },
481*b636d99dSDavid van Moolenbroek /* 26 */
482*b636d99dSDavid van Moolenbroek { SCTP_PPID_X2AP, "X2AP" },
483*b636d99dSDavid van Moolenbroek { 0, NULL }
484*b636d99dSDavid van Moolenbroek };
485*b636d99dSDavid van Moolenbroek
486*b636d99dSDavid van Moolenbroek
isForCES_port(u_short Port)487*b636d99dSDavid van Moolenbroek static inline int isForCES_port(u_short Port)
488*b636d99dSDavid van Moolenbroek {
489*b636d99dSDavid van Moolenbroek if (Port == CHAN_HP)
490*b636d99dSDavid van Moolenbroek return 1;
491*b636d99dSDavid van Moolenbroek if (Port == CHAN_MP)
492*b636d99dSDavid van Moolenbroek return 1;
493*b636d99dSDavid van Moolenbroek if (Port == CHAN_LP)
494*b636d99dSDavid van Moolenbroek return 1;
495*b636d99dSDavid van Moolenbroek
496*b636d99dSDavid van Moolenbroek return 0;
497*b636d99dSDavid van Moolenbroek }
498*b636d99dSDavid van Moolenbroek
sctp_print(netdissect_options * ndo,const u_char * bp,const u_char * bp2,u_int sctpPacketLength)499*b636d99dSDavid van Moolenbroek void sctp_print(netdissect_options *ndo,
500*b636d99dSDavid van Moolenbroek const u_char *bp, /* beginning of sctp packet */
501*b636d99dSDavid van Moolenbroek const u_char *bp2, /* beginning of enclosing */
502*b636d99dSDavid van Moolenbroek u_int sctpPacketLength) /* ip packet */
503*b636d99dSDavid van Moolenbroek {
504*b636d99dSDavid van Moolenbroek const struct sctpHeader *sctpPktHdr;
505*b636d99dSDavid van Moolenbroek const struct ip *ip;
506*b636d99dSDavid van Moolenbroek #ifdef INET6
507*b636d99dSDavid van Moolenbroek const struct ip6_hdr *ip6;
508*b636d99dSDavid van Moolenbroek #endif
509*b636d99dSDavid van Moolenbroek const void *endPacketPtr;
510*b636d99dSDavid van Moolenbroek u_short sourcePort, destPort;
511*b636d99dSDavid van Moolenbroek int chunkCount;
512*b636d99dSDavid van Moolenbroek const struct sctpChunkDesc *chunkDescPtr;
513*b636d99dSDavid van Moolenbroek const void *nextChunk;
514*b636d99dSDavid van Moolenbroek const char *sep;
515*b636d99dSDavid van Moolenbroek int isforces = 0;
516*b636d99dSDavid van Moolenbroek
517*b636d99dSDavid van Moolenbroek
518*b636d99dSDavid van Moolenbroek sctpPktHdr = (const struct sctpHeader*) bp;
519*b636d99dSDavid van Moolenbroek endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;
520*b636d99dSDavid van Moolenbroek
521*b636d99dSDavid van Moolenbroek if( (u_long) endPacketPtr > (u_long) ndo->ndo_snapend)
522*b636d99dSDavid van Moolenbroek endPacketPtr = (const void *) ndo->ndo_snapend;
523*b636d99dSDavid van Moolenbroek ip = (struct ip *)bp2;
524*b636d99dSDavid van Moolenbroek #ifdef INET6
525*b636d99dSDavid van Moolenbroek if (IP_V(ip) == 6)
526*b636d99dSDavid van Moolenbroek ip6 = (const struct ip6_hdr *)bp2;
527*b636d99dSDavid van Moolenbroek else
528*b636d99dSDavid van Moolenbroek ip6 = NULL;
529*b636d99dSDavid van Moolenbroek #endif /*INET6*/
530*b636d99dSDavid van Moolenbroek ND_TCHECK(*sctpPktHdr);
531*b636d99dSDavid van Moolenbroek
532*b636d99dSDavid van Moolenbroek if (sctpPacketLength < sizeof(struct sctpHeader))
533*b636d99dSDavid van Moolenbroek {
534*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "truncated-sctp - %ld bytes missing!",
535*b636d99dSDavid van Moolenbroek (long)sctpPacketLength-sizeof(struct sctpHeader)));
536*b636d99dSDavid van Moolenbroek return;
537*b636d99dSDavid van Moolenbroek }
538*b636d99dSDavid van Moolenbroek
539*b636d99dSDavid van Moolenbroek /* sctpPacketLength -= sizeof(struct sctpHeader); packet length */
540*b636d99dSDavid van Moolenbroek /* is now only as long as the payload */
541*b636d99dSDavid van Moolenbroek
542*b636d99dSDavid van Moolenbroek sourcePort = EXTRACT_16BITS(&sctpPktHdr->source);
543*b636d99dSDavid van Moolenbroek destPort = EXTRACT_16BITS(&sctpPktHdr->destination);
544*b636d99dSDavid van Moolenbroek
545*b636d99dSDavid van Moolenbroek #ifdef INET6
546*b636d99dSDavid van Moolenbroek if (ip6) {
547*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s.%d > %s.%d: sctp",
548*b636d99dSDavid van Moolenbroek ip6addr_string(ndo, &ip6->ip6_src),
549*b636d99dSDavid van Moolenbroek sourcePort,
550*b636d99dSDavid van Moolenbroek ip6addr_string(ndo, &ip6->ip6_dst),
551*b636d99dSDavid van Moolenbroek destPort));
552*b636d99dSDavid van Moolenbroek } else
553*b636d99dSDavid van Moolenbroek #endif /*INET6*/
554*b636d99dSDavid van Moolenbroek {
555*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s.%d > %s.%d: sctp",
556*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &ip->ip_src),
557*b636d99dSDavid van Moolenbroek sourcePort,
558*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &ip->ip_dst),
559*b636d99dSDavid van Moolenbroek destPort));
560*b636d99dSDavid van Moolenbroek }
561*b636d99dSDavid van Moolenbroek
562*b636d99dSDavid van Moolenbroek if (isForCES_port(sourcePort)) {
563*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[%s]", tok2str(ForCES_channels, NULL, sourcePort)));
564*b636d99dSDavid van Moolenbroek isforces = 1;
565*b636d99dSDavid van Moolenbroek }
566*b636d99dSDavid van Moolenbroek if (isForCES_port(destPort)) {
567*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[%s]", tok2str(ForCES_channels, NULL, destPort)));
568*b636d99dSDavid van Moolenbroek isforces = 1;
569*b636d99dSDavid van Moolenbroek }
570*b636d99dSDavid van Moolenbroek
571*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag >= 2)
572*b636d99dSDavid van Moolenbroek sep = "\n\t";
573*b636d99dSDavid van Moolenbroek else
574*b636d99dSDavid van Moolenbroek sep = " (";
575*b636d99dSDavid van Moolenbroek /* cycle through all chunks, printing information on each one */
576*b636d99dSDavid van Moolenbroek for (chunkCount = 0,
577*b636d99dSDavid van Moolenbroek chunkDescPtr = (const struct sctpChunkDesc *)
578*b636d99dSDavid van Moolenbroek ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader));
579*b636d99dSDavid van Moolenbroek chunkDescPtr != NULL &&
580*b636d99dSDavid van Moolenbroek ( (const void *)
581*b636d99dSDavid van Moolenbroek ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc))
582*b636d99dSDavid van Moolenbroek <= endPacketPtr);
583*b636d99dSDavid van Moolenbroek
584*b636d99dSDavid van Moolenbroek chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++)
585*b636d99dSDavid van Moolenbroek {
586*b636d99dSDavid van Moolenbroek uint16_t chunkLength;
587*b636d99dSDavid van Moolenbroek const u_char *chunkEnd;
588*b636d99dSDavid van Moolenbroek uint16_t align;
589*b636d99dSDavid van Moolenbroek
590*b636d99dSDavid van Moolenbroek ND_TCHECK(*chunkDescPtr);
591*b636d99dSDavid van Moolenbroek chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength);
592*b636d99dSDavid van Moolenbroek if (chunkLength < sizeof(*chunkDescPtr)) {
593*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength));
594*b636d99dSDavid van Moolenbroek break;
595*b636d99dSDavid van Moolenbroek }
596*b636d99dSDavid van Moolenbroek
597*b636d99dSDavid van Moolenbroek ND_TCHECK2(*((uint8_t *)chunkDescPtr), chunkLength);
598*b636d99dSDavid van Moolenbroek chunkEnd = ((const u_char*)chunkDescPtr + chunkLength);
599*b636d99dSDavid van Moolenbroek
600*b636d99dSDavid van Moolenbroek align=chunkLength % 4;
601*b636d99dSDavid van Moolenbroek if (align != 0)
602*b636d99dSDavid van Moolenbroek align = 4 - align;
603*b636d99dSDavid van Moolenbroek
604*b636d99dSDavid van Moolenbroek nextChunk = (const void *) (chunkEnd + align);
605*b636d99dSDavid van Moolenbroek
606*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s%d) ", sep, chunkCount+1));
607*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[%s] ", tok2str(sctp_chunkid_str, "Unknown chunk type: 0x%x",
608*b636d99dSDavid van Moolenbroek chunkDescPtr->chunkID)));
609*b636d99dSDavid van Moolenbroek switch (chunkDescPtr->chunkID)
610*b636d99dSDavid van Moolenbroek {
611*b636d99dSDavid van Moolenbroek case SCTP_DATA :
612*b636d99dSDavid van Moolenbroek {
613*b636d99dSDavid van Moolenbroek const struct sctpDataPart *dataHdrPtr;
614*b636d99dSDavid van Moolenbroek uint32_t ppid;
615*b636d99dSDavid van Moolenbroek const u_char *payloadPtr;
616*b636d99dSDavid van Moolenbroek u_int payload_size;
617*b636d99dSDavid van Moolenbroek
618*b636d99dSDavid van Moolenbroek if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
619*b636d99dSDavid van Moolenbroek == SCTP_DATA_UNORDERED)
620*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "(U)"));
621*b636d99dSDavid van Moolenbroek
622*b636d99dSDavid van Moolenbroek if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
623*b636d99dSDavid van Moolenbroek == SCTP_DATA_FIRST_FRAG)
624*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "(B)"));
625*b636d99dSDavid van Moolenbroek
626*b636d99dSDavid van Moolenbroek if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
627*b636d99dSDavid van Moolenbroek == SCTP_DATA_LAST_FRAG)
628*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "(E)"));
629*b636d99dSDavid van Moolenbroek
630*b636d99dSDavid van Moolenbroek if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
631*b636d99dSDavid van Moolenbroek == SCTP_DATA_UNORDERED)
632*b636d99dSDavid van Moolenbroek ||
633*b636d99dSDavid van Moolenbroek ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
634*b636d99dSDavid van Moolenbroek == SCTP_DATA_FIRST_FRAG)
635*b636d99dSDavid van Moolenbroek ||
636*b636d99dSDavid van Moolenbroek ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
637*b636d99dSDavid van Moolenbroek == SCTP_DATA_LAST_FRAG) )
638*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " "));
639*b636d99dSDavid van Moolenbroek
640*b636d99dSDavid van Moolenbroek dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1);
641*b636d99dSDavid van Moolenbroek
642*b636d99dSDavid van Moolenbroek ppid = EXTRACT_32BITS(&dataHdrPtr->payloadtype);
643*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN)));
644*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId)));
645*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence)));
646*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[PPID %s] ",
647*b636d99dSDavid van Moolenbroek tok2str(PayloadProto_idents, "0x%x", ppid)));
648*b636d99dSDavid van Moolenbroek
649*b636d99dSDavid van Moolenbroek if (!isforces) {
650*b636d99dSDavid van Moolenbroek isforces = (ppid == SCTP_PPID_FORCES_HP) ||
651*b636d99dSDavid van Moolenbroek (ppid == SCTP_PPID_FORCES_MP) ||
652*b636d99dSDavid van Moolenbroek (ppid == SCTP_PPID_FORCES_LP);
653*b636d99dSDavid van Moolenbroek }
654*b636d99dSDavid van Moolenbroek
655*b636d99dSDavid van Moolenbroek payloadPtr = (const u_char *) (dataHdrPtr + 1);
656*b636d99dSDavid van Moolenbroek if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
657*b636d99dSDavid van Moolenbroek sizeof(struct sctpDataPart) + sizeof(struct sctpChunkDesc) + 1) {
658*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "bogus chunk length %u]", EXTRACT_16BITS(&chunkDescPtr->chunkLength)));
659*b636d99dSDavid van Moolenbroek return;
660*b636d99dSDavid van Moolenbroek }
661*b636d99dSDavid van Moolenbroek
662*b636d99dSDavid van Moolenbroek payload_size = EXTRACT_16BITS(&chunkDescPtr->chunkLength) -
663*b636d99dSDavid van Moolenbroek (sizeof(struct sctpDataPart) + sizeof(struct sctpChunkDesc));
664*b636d99dSDavid van Moolenbroek
665*b636d99dSDavid van Moolenbroek if (isforces) {
666*b636d99dSDavid van Moolenbroek forces_print(ndo, payloadPtr, payload_size);
667*b636d99dSDavid van Moolenbroek } else if (ndo->ndo_vflag >= 2) { /* if verbose output is specified */
668*b636d99dSDavid van Moolenbroek /* at the command line */
669*b636d99dSDavid van Moolenbroek switch (ppid) {
670*b636d99dSDavid van Moolenbroek case SCTP_PPID_M3UA :
671*b636d99dSDavid van Moolenbroek m3ua_print(ndo, payloadPtr, payload_size);
672*b636d99dSDavid van Moolenbroek break;
673*b636d99dSDavid van Moolenbroek default:
674*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[Payload"));
675*b636d99dSDavid van Moolenbroek if (!ndo->ndo_suppress_default_print) {
676*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ":"));
677*b636d99dSDavid van Moolenbroek ND_DEFAULTPRINT(payloadPtr, payload_size);
678*b636d99dSDavid van Moolenbroek }
679*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "]"));
680*b636d99dSDavid van Moolenbroek break;
681*b636d99dSDavid van Moolenbroek }
682*b636d99dSDavid van Moolenbroek }
683*b636d99dSDavid van Moolenbroek break;
684*b636d99dSDavid van Moolenbroek }
685*b636d99dSDavid van Moolenbroek case SCTP_INITIATION :
686*b636d99dSDavid van Moolenbroek {
687*b636d99dSDavid van Moolenbroek const struct sctpInitiation *init;
688*b636d99dSDavid van Moolenbroek
689*b636d99dSDavid van Moolenbroek init=(const struct sctpInitiation*)(chunkDescPtr+1);
690*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[init tag: %u] ", EXTRACT_32BITS(&init->initTag)));
691*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit)));
692*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams)));
693*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams)));
694*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN)));
695*b636d99dSDavid van Moolenbroek
696*b636d99dSDavid van Moolenbroek #if(0) /* ALC you can add code for optional params here */
697*b636d99dSDavid van Moolenbroek if( (init+1) < chunkEnd )
698*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " @@@@@ UNFINISHED @@@@@@%s\n",
699*b636d99dSDavid van Moolenbroek "Optional params present, but not printed."));
700*b636d99dSDavid van Moolenbroek #endif
701*b636d99dSDavid van Moolenbroek break;
702*b636d99dSDavid van Moolenbroek }
703*b636d99dSDavid van Moolenbroek case SCTP_INITIATION_ACK :
704*b636d99dSDavid van Moolenbroek {
705*b636d99dSDavid van Moolenbroek const struct sctpInitiation *init;
706*b636d99dSDavid van Moolenbroek
707*b636d99dSDavid van Moolenbroek init=(const struct sctpInitiation*)(chunkDescPtr+1);
708*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[init tag: %u] ", EXTRACT_32BITS(&init->initTag)));
709*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit)));
710*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams)));
711*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams)));
712*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN)));
713*b636d99dSDavid van Moolenbroek
714*b636d99dSDavid van Moolenbroek #if(0) /* ALC you can add code for optional params here */
715*b636d99dSDavid van Moolenbroek if( (init+1) < chunkEnd )
716*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " @@@@@ UNFINISHED @@@@@@%s\n",
717*b636d99dSDavid van Moolenbroek "Optional params present, but not printed."));
718*b636d99dSDavid van Moolenbroek #endif
719*b636d99dSDavid van Moolenbroek break;
720*b636d99dSDavid van Moolenbroek }
721*b636d99dSDavid van Moolenbroek case SCTP_SELECTIVE_ACK:
722*b636d99dSDavid van Moolenbroek {
723*b636d99dSDavid van Moolenbroek const struct sctpSelectiveAck *sack;
724*b636d99dSDavid van Moolenbroek const struct sctpSelectiveFrag *frag;
725*b636d99dSDavid van Moolenbroek int fragNo, tsnNo;
726*b636d99dSDavid van Moolenbroek const u_char *dupTSN;
727*b636d99dSDavid van Moolenbroek
728*b636d99dSDavid van Moolenbroek sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1);
729*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN)));
730*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd)));
731*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc)));
732*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns)));
733*b636d99dSDavid van Moolenbroek
734*b636d99dSDavid van Moolenbroek
735*b636d99dSDavid van Moolenbroek /* print gaps */
736*b636d99dSDavid van Moolenbroek for (frag = ( (const struct sctpSelectiveFrag *)
737*b636d99dSDavid van Moolenbroek ((const struct sctpSelectiveAck *) sack+1)),
738*b636d99dSDavid van Moolenbroek fragNo=0;
739*b636d99dSDavid van Moolenbroek (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc);
740*b636d99dSDavid van Moolenbroek frag++, fragNo++)
741*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\t[gap ack block #%d: start = %u, end = %u] ",
742*b636d99dSDavid van Moolenbroek fragNo+1,
743*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart),
744*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd)));
745*b636d99dSDavid van Moolenbroek
746*b636d99dSDavid van Moolenbroek
747*b636d99dSDavid van Moolenbroek /* print duplicate TSNs */
748*b636d99dSDavid van Moolenbroek for (dupTSN = (const u_char *)frag, tsnNo=0;
749*b636d99dSDavid van Moolenbroek (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
750*b636d99dSDavid van Moolenbroek dupTSN += 4, tsnNo++)
751*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
752*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(dupTSN)));
753*b636d99dSDavid van Moolenbroek
754*b636d99dSDavid van Moolenbroek break;
755*b636d99dSDavid van Moolenbroek }
756*b636d99dSDavid van Moolenbroek }
757*b636d99dSDavid van Moolenbroek
758*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag < 2)
759*b636d99dSDavid van Moolenbroek sep = ", (";
760*b636d99dSDavid van Moolenbroek }
761*b636d99dSDavid van Moolenbroek return;
762*b636d99dSDavid van Moolenbroek
763*b636d99dSDavid van Moolenbroek trunc:
764*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[|sctp]"));
765*b636d99dSDavid van Moolenbroek }
766