Skip to content

Commit f13fabd

Browse files
author
Yuxuan Luo
committed
SCTP: Support I-DATA chunk
Add support for printing SCTP I-DATA chunk based on RFC8260 section 2.1 Prints payload when vflag level is greater than 1. Example: [I-DATA] (B) [TSN: 1522458896] [SID: 0] [MID: 0] [PPID 0x0] [I-DATA] (E) [TSN: 1522458897] [SID: 0] [MID: 0] [FSN: 0]
1 parent 80f4fbf commit f13fabd

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

print-sctp.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
#define SCTP_ECN_ECHO 0x0c
112112
#define SCTP_ECN_CWR 0x0d
113113
#define SCTP_SHUTDOWN_COMPLETE 0x0e
114+
#define SCTP_I_DATA 0x40
114115
#define SCTP_FORWARD_CUM_TSN 0xc0
115116
#define SCTP_RELIABLE_CNTL 0xc1
116117
#define SCTP_RELIABLE_CNTL_ACK 0xc2
@@ -131,6 +132,7 @@ static const struct tok sctp_chunkid_str[] = {
131132
{ SCTP_ECN_ECHO, "ECN ECHO" },
132133
{ SCTP_ECN_CWR, "ECN CWR" },
133134
{ SCTP_SHUTDOWN_COMPLETE, "SHUTDOWN COMPLETE" },
135+
{ SCTP_I_DATA, "I-DATA" },
134136
{ SCTP_FORWARD_CUM_TSN, "FOR CUM TSN" },
135137
{ SCTP_RELIABLE_CNTL, "REL CTRL" },
136138
{ SCTP_RELIABLE_CNTL_ACK, "REL CTRL ACK" },
@@ -144,6 +146,7 @@ static const struct tok sctp_chunkid_str[] = {
144146
#define SCTP_DATA_FIRST_FRAG 0x02
145147
#define SCTP_DATA_NOT_FRAG 0x03
146148
#define SCTP_DATA_UNORDERED 0x04
149+
#define SCTP_DATA_SACK_IMM 0x08
147150

148151
#define SCTP_ADDRMAX 60
149152

@@ -350,6 +353,14 @@ struct sctpDataPart{
350353
nd_uint32_t payloadtype;
351354
};
352355

356+
struct sctpIData{
357+
nd_uint32_t TSN;
358+
nd_uint16_t streamId;
359+
nd_uint16_t reserved;
360+
nd_uint32_t MID;
361+
nd_uint32_t PPID_FSN;
362+
};
363+
353364
struct sctpUnifiedDatagram{
354365
struct sctpChunkDesc uh;
355366
struct sctpDataPart dp;
@@ -619,6 +630,100 @@ sctp_print(netdissect_options *ndo,
619630
break;
620631
}
621632
}
633+
bp += payload_size;
634+
sctpPacketLengthRemaining -= payload_size;
635+
chunkLengthRemaining -= payload_size;
636+
break;
637+
}
638+
case SCTP_I_DATA :
639+
{
640+
const struct sctpIData *dataHdrPtr;
641+
uint8_t Bbit = FALSE;
642+
uint8_t chunkFlg;
643+
uint32_t ppid_fsn;
644+
uint16_t payload_size;
645+
646+
chunkFlg = GET_U_1(chunkDescPtr->chunkFlg);
647+
if ((chunkFlg & SCTP_DATA_SACK_IMM) == SCTP_DATA_SACK_IMM)
648+
ND_PRINT("(I)");
649+
650+
if ((chunkFlg & SCTP_DATA_UNORDERED) == SCTP_DATA_UNORDERED)
651+
ND_PRINT("(U)");
652+
653+
if ((chunkFlg & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG) {
654+
ND_PRINT("(B)");
655+
Bbit = TRUE;
656+
}
657+
658+
if ((chunkFlg & SCTP_DATA_LAST_FRAG) == SCTP_DATA_LAST_FRAG)
659+
ND_PRINT("(E)");
660+
661+
if (((chunkFlg & SCTP_DATA_UNORDERED) == SCTP_DATA_UNORDERED) ||
662+
((chunkFlg & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG) ||
663+
((chunkFlg & SCTP_DATA_LAST_FRAG) == SCTP_DATA_LAST_FRAG) )
664+
ND_PRINT(" ");
665+
666+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(*dataHdrPtr));
667+
dataHdrPtr=(const struct sctpIData*)bp;
668+
669+
ppid_fsn = GET_BE_U_4(dataHdrPtr->PPID_FSN);
670+
ND_PRINT("[TSN: %u] ", GET_BE_U_4(dataHdrPtr->TSN));
671+
ND_PRINT("[SID: %u] ", GET_BE_U_2(dataHdrPtr->streamId));
672+
ND_PRINT("[MID: %u] ", GET_BE_U_4(dataHdrPtr->MID));
673+
if (FALSE == Bbit) { /* print FSN if B bit is NOT set */
674+
ND_PRINT("[FSN: %u] ", ppid_fsn);
675+
} else { /* print PPID if B bit is set */
676+
ND_PRINT("[PPID %s] ", tok2str(PayloadProto_idents, "0x%x", ppid_fsn));
677+
}
678+
679+
bp += sizeof(*dataHdrPtr);
680+
sctpPacketLengthRemaining -= sizeof(*dataHdrPtr);
681+
chunkLengthRemaining -= sizeof(*dataHdrPtr);
682+
ND_ICHECKMSG_U("chunk length", chunkLengthRemaining, ==, 0)
683+
payload_size = chunkLengthRemaining;
684+
685+
if (FALSE == Bbit) {
686+
if (ndo->ndo_vflag >= 2) {
687+
ND_PRINT("[Payload");
688+
if (!ndo->ndo_suppress_default_print) {
689+
ND_PRINT(": ");
690+
ND_DEFAULTPRINT(bp, payload_size);
691+
}
692+
ND_PRINT("]");
693+
}
694+
695+
bp += payload_size;
696+
sctpPacketLengthRemaining -= payload_size;
697+
chunkLengthRemaining -= payload_size;
698+
break; /* do not parse ppid and check for CES when B bit is set */
699+
}
700+
701+
if (!isforces) {
702+
isforces = (ppid_fsn == SCTP_PPID_FORCES_HP) ||
703+
(ppid_fsn == SCTP_PPID_FORCES_MP) ||
704+
(ppid_fsn == SCTP_PPID_FORCES_LP);
705+
}
706+
707+
if (isforces) {
708+
forces_print(ndo, bp, payload_size);
709+
ndo->ndo_protocol = "sctp";
710+
} else if (ndo->ndo_vflag >= 2) {
711+
switch (ppid_fsn) {
712+
case SCTP_PPID_M3UA:
713+
m3ua_print(ndo, bp, payload_size);
714+
ndo->ndo_protocol = "sctp";
715+
break;
716+
default:
717+
ND_PRINT("[Payload");
718+
if (!ndo->ndo_suppress_default_print) {
719+
ND_PRINT(":");
720+
ND_DEFAULTPRINT(bp, payload_size);
721+
}
722+
ND_PRINT("]");
723+
break;
724+
}
725+
}
726+
622727
bp += payload_size;
623728
sctpPacketLengthRemaining -= payload_size;
624729
chunkLengthRemaining -= payload_size;

0 commit comments

Comments
 (0)