]>
The Tcpdump Group git mirrors - tcpdump/blob - print-sctp.c
1 /* Copyright (c) 2001 NETLAB, Temple University
2 * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware
4 * Jerry Heinz <gheinz@astro.temple.edu>
5 * John Fiore <jfiore@joda.cis.temple.edu>
6 * Armando L. Caro Jr. <acaro@cis.udel.edu>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor of the Laboratory may be used
20 * to endorse or promote products derived from this software without
21 * specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 static const char rcsid
[] =
38 "@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.2 2001-05-09 01:25:44 fenner Exp $ (NETLAB/PEL)";
45 #include <sys/param.h>
47 #include <sys/socket.h>
50 #include "sctpHeader.h"
51 #include "sctpConstants.h"
60 #include <netinet/in.h>
65 #include "interface.h"
66 #include "addrtoname.h"
67 #include "extract.h" /* must come after interface.h */
73 void sctp_print(const u_char
*bp
, /* beginning of sctp packet */
74 const u_char
*bp2
, /* beginning of enclosing */
75 u_int sctpPacketLength
) /* ip packet */
77 const struct sctpHeader
*sctpPktHdr
;
80 const struct ip6_hdr
*ip6
;
84 u_short sourcePort
, destPort
;
86 struct sctpChunkDesc
*chunkDescPtr
;
89 sctpPktHdr
= (struct sctpHeader
*) bp
;
90 endPacketPtr
= ((u_char
*)((u_char
*)sctpPktHdr
+sctpPacketLength
));
92 if( (u_long
) endPacketPtr
> (u_long
) snapend
)
93 endPacketPtr
= (void *) snapend
;
94 ip
= (struct ip
*)bp2
;
97 ip6
= (struct ip6_hdr
*)bp2
;
101 cp
= (u_char
*)(sctpPktHdr
+ 1);
108 if (sctpPacketLength
< sizeof(struct sctpHeader
))
110 (void)printf("truncated-sctp - %d bytes missing!",
111 sctpPacketLength
-sizeof(struct sctpHeader
));
115 /* sctpPacketLength -= sizeof(struct sctpHeader); packet length */
116 /* is now only as long as the payload */
118 sourcePort
= ntohs(sctpPktHdr
->source
);
119 destPort
= ntohs(sctpPktHdr
->destination
);
123 if (ip6
->ip6_nxt
== IPPROTO_SCTP
) {
124 (void)printf("%s.%d > %s.%d: sctp",
125 ip6addr_string(&ip6
->ip6_src
),
127 ip6addr_string(&ip6
->ip6_dst
),
130 (void)printf("%d > %d: sctp",
131 sourcePort
, destPort
);
136 if (ip
->ip_p
== IPPROTO_SCTP
) {
137 (void)printf("%s.%d > %s.%d: sctp",
138 ipaddr_string(&ip
->ip_src
),
140 ipaddr_string(&ip
->ip_dst
),
143 (void)printf("%d > %d: sctp",
144 sourcePort
, destPort
);
152 /* cycle through all chunks, printing information on each one */
154 chunkDescPtr
= (struct sctpChunkDesc
*) ( (u_char
*) sctpPktHdr
+
155 sizeof(struct sctpHeader
));
156 chunkDescPtr
!= NULL
&&
157 ( (void *) ((u_char
*) chunkDescPtr
+ sizeof(struct sctpChunkDesc
))
160 chunkDescPtr
= (struct sctpChunkDesc
*) nextChunk
, chunkCount
++)
165 chunkEnd
= ((u_char
*)chunkDescPtr
+ ntohs(chunkDescPtr
->chunkLength
));
167 align
=ntohs(chunkDescPtr
->chunkLength
) % 4;
171 nextChunk
= (void *) (chunkEnd
+ align
);
173 printf("\n\t%d) ", chunkCount
+1);
174 switch (chunkDescPtr
->chunkID
)
178 struct sctpDataPart
*dataHdrPtr
;
182 if ((chunkDescPtr
->chunkFlg
& SCTP_DATA_UNORDERED
)
183 == SCTP_DATA_UNORDERED
)
186 if ((chunkDescPtr
->chunkFlg
& SCTP_DATA_FIRST_FRAG
)
187 == SCTP_DATA_FIRST_FRAG
)
190 if ((chunkDescPtr
->chunkFlg
& SCTP_DATA_LAST_FRAG
)
191 == SCTP_DATA_LAST_FRAG
)
194 if( ((chunkDescPtr
->chunkFlg
& SCTP_DATA_UNORDERED
)
195 == SCTP_DATA_UNORDERED
)
197 ((chunkDescPtr
->chunkFlg
& SCTP_DATA_FIRST_FRAG
)
198 == SCTP_DATA_FIRST_FRAG
)
200 ((chunkDescPtr
->chunkFlg
& SCTP_DATA_LAST_FRAG
)
201 == SCTP_DATA_LAST_FRAG
) )
204 dataHdrPtr
=(struct sctpDataPart
*)(chunkDescPtr
+1);
206 printf("[TSN: %lu] ", ntohl(dataHdrPtr
->TSN
));
207 printf("[SID: %u] ", ntohs(dataHdrPtr
->streamId
));
208 printf("[SSEQ %u] ", ntohs(dataHdrPtr
->sequence
));
209 printf("[PPID 0x%x] ", (u_int32_t
)ntohl(dataHdrPtr
->payloadtype
));
212 if (vflag
) /* if verbose output is specified */
213 { /* at the command line */
216 printf("[Payload: {");
219 payloadPtr
= (char *) (++dataHdrPtr
);
220 write(STDOUT_FILENO
, payloadPtr
,
221 htons(chunkDescPtr
->chunkLength
)-1 -
222 sizeof(struct sctpDataPart
)-sizeof(struct sctpChunkDesc
));
228 case SCTP_INITIATION
:
230 struct sctpInitiation
*init
;
233 init
=(struct sctpInitiation
*)(chunkDescPtr
+1);
234 printf("[init tag: %lu] ", ntohl(init
->initTag
));
235 printf("[rwnd: %lu] ", ntohl(init
->rcvWindowCredit
));
236 printf("[OS: %u] ", ntohs(init
->NumPreopenStreams
));
237 printf("[MIS: %u] ", ntohs(init
->MaxInboundStreams
));
238 printf("[init TSN: %lu] ", ntohl(init
->initialTSN
));
240 #if(0) /* ALC you can add code for optional params here */
241 if( (init
+1) < chunkEnd
)
242 printf(" @@@@@ UNFINISHED @@@@@@%s\n",
243 "Optional params present, but not printed.");
247 case SCTP_INITIATION_ACK
:
249 struct sctpInitiation
*init
;
251 printf("[INIT ACK] ");
252 init
=(struct sctpInitiation
*)(chunkDescPtr
+1);
253 printf("[init tag: %lu] ", ntohl(init
->initTag
));
254 printf("[rwnd: %lu] ", ntohl(init
->rcvWindowCredit
));
255 printf("[OS: %u] ", ntohs(init
->NumPreopenStreams
));
256 printf("[MIS: %u] ", ntohs(init
->MaxInboundStreams
));
257 printf("[init TSN: %lu] ", ntohl(init
->initialTSN
));
259 #if(0) /* ALC you can add code for optional params here */
260 if( (init
+1) < chunkEnd
)
261 printf(" @@@@@ UNFINISHED @@@@@@%s\n",
262 "Optional params present, but not printed.");
266 case SCTP_SELECTIVE_ACK
:
268 struct sctpSelectiveAck
*sack
;
269 struct sctpSelectiveFrag
*frag
;
274 sack
=(struct sctpSelectiveAck
*)(chunkDescPtr
+1);
275 printf("[cum ack %lu] ", ntohl(sack
->highestConseqTSN
));
276 printf("[a_rwnd %lu] ", ntohl(sack
->updatedRwnd
));
277 printf("[#gap acks %u] ", ntohs(sack
->numberOfdesc
));
278 printf("[#dup tsns %u] ", ntohs(sack
->numDupTsns
));
282 for (frag
= ( (struct sctpSelectiveFrag
*)
283 ((struct sctpSelectiveAck
*) sack
+1)),
285 (void *)frag
< nextChunk
&& fragNo
< ntohs(sack
->numberOfdesc
);
287 printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ",
289 (u_int32_t
)(ntohl(sack
->highestConseqTSN
) + ntohs(frag
->fragmentStart
)),
290 (u_int32_t
)(ntohl(sack
->highestConseqTSN
) + ntohs(frag
->fragmentEnd
)));
293 /* print duplicate TSNs */
294 for (dupTSN
= (u_long
*)frag
, tsnNo
=0;
295 (void *) dupTSN
< nextChunk
&& tsnNo
<ntohs(sack
->numDupTsns
);
297 printf("\n\t\t[dup TSN #%u: %lu] ", tsnNo
+1, ntohl(*dupTSN
));
301 case SCTP_HEARTBEAT_REQUEST
:
303 struct sctpHBsender
*hb
;
305 hb
=(struct sctpHBsender
*)chunkDescPtr
;
311 case SCTP_HEARTBEAT_ACK
:
314 case SCTP_ABORT_ASSOCIATION
:
318 printf("[SHUTDOWN] ");
320 case SCTP_SHUTDOWN_ACK
:
321 printf("[SHUTDOWN ACK] ");
323 case SCTP_OPERATION_ERR
:
326 case SCTP_COOKIE_ECHO
:
327 printf("[COOKIE ECHO] ");
329 case SCTP_COOKIE_ACK
:
330 printf("[COOKIE ACK] ");
333 printf("[ECN ECHO] ");
336 printf("[ECN CWR] ");
338 case SCTP_SHUTDOWN_COMPLETE
:
339 printf("[SHUTDOWN COMPLETE] ");
341 case SCTP_FORWARD_CUM_TSN
:
342 printf("[FOR CUM TSN] ");
344 case SCTP_RELIABLE_CNTL
:
345 printf("[REL CTRL] ");
347 case SCTP_RELIABLE_CNTL_ACK
:
348 printf("[REL CTRL ACK] ");
351 printf("[Unknown chunk type: 0x%x]", chunkDescPtr
->chunkID
);