Skip to content

Commit 1ebb798

Browse files
Yuxuan LuoCacheUseOnly
Yuxuan Luo
authored andcommitted
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 8e1661b commit 1ebb798

File tree

6 files changed

+526
-0
lines changed

6 files changed

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

tests/TESTLIST

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ tcp_rst_data tcp_rst_data.pcap tcp_rst_data.out -v
4343
# TCP with data in the RST segment, truncated example
4444
tcp_rst_data-trunc tcp_rst_data-trunc.pcap tcp_rst_data-trunc.out -v
4545

46+
# SCTP tests
47+
# I-DATA tests
48+
sctp-i-data sctp-i-data.pcap sctp-i-data.out
49+
sctp-i-data-v sctp-i-data.pcap sctp-i-data-v.out -v
50+
sctp-i-data-vv sctp-i-data.pcap sctp-i-data-vv.out -vv
51+
4652
# BGP tests
4753
bgp_vpn_attrset bgp_vpn_attrset.pcap bgp_vpn_attrset.out -v
4854
mpbgp-linklocal-nexthop mpbgp-linklocal-nexthop.pcap mpbgp-linklocal-nexthop.out -v

tests/sctp-i-data-v.out

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
1 19:45:01.497381 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 92)
2+
192.168.5.1.36413 > 192.168.5.2.36297: sctp (1) [INIT] [init tag: 3820459860] [rwnd: 106496] [OS: 10] [MIS: 65535] [init TSN: 2906273895]
3+
2 19:45:01.497403 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 348)
4+
192.168.5.2.36297 > 192.168.5.1.36413: sctp (1) [INIT ACK] [init tag: 3868939720] [rwnd: 106496] [OS: 5] [MIS: 5] [init TSN: 2320017092]
5+
3 19:45:01.497422 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 296)
6+
192.168.5.1.36413 > 192.168.5.2.36297: sctp (1) [COOKIE ECHO]
7+
4 19:45:01.497437 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 36)
8+
192.168.5.2.36297 > 192.168.5.1.36413: sctp (1) [COOKIE ACK]
9+
5 19:45:01.497461 IP (tos 0x2,ECT(0), ttl 64, id 1, offset 0, flags [DF], proto SCTP (132), length 1500)
10+
192.168.5.1.36413 > 192.168.5.2.36297: sctp (1) [I-DATA] (B) [TSN: 2906273895] [SID: 0] [MID: 0] [PPID 0x0]
11+
6 19:45:01.497469 IP (tos 0x2,ECT(0), ttl 64, id 44213, offset 0, flags [DF], proto SCTP (132), length 48)
12+
192.168.5.2.36297 > 192.168.5.1.36413: sctp (1) [SACK] [cum ack 2906273895] [a_rwnd 105048] [#gap acks 0] [#dup tsns 0]
13+
7 19:45:01.497473 IP (tos 0x2,ECT(0), ttl 64, id 2, offset 0, flags [DF], proto SCTP (132), length 1276)
14+
192.168.5.1.36413 > 192.168.5.2.36297: sctp (1) [I-DATA] (E) [TSN: 2906273896] [SID: 0] [MID: 0] [FSN: 0]
15+
8 19:45:01.497529 IP (tos 0x2,ECT(0), ttl 64, id 44214, offset 0, flags [DF], proto SCTP (132), length 1500)
16+
192.168.5.2.36297 > 192.168.5.1.36413: sctp (1) [SACK] [cum ack 2906273896] [a_rwnd 106496] [#gap acks 0] [#dup tsns 0] , (2) [I-DATA] (B) [TSN: 2320017092] [SID: 0] [MID: 0] [PPID 0x0]
17+
9 19:45:01.497539 IP (tos 0x2,ECT(0), ttl 64, id 3, offset 0, flags [DF], proto SCTP (132), length 48)
18+
192.168.5.1.36413 > 192.168.5.2.36297: sctp (1) [SACK] [cum ack 2320017092] [a_rwnd 105064] [#gap acks 0] [#dup tsns 0]
19+
10 19:45:01.497543 IP (tos 0x2,ECT(0), ttl 64, id 44215, offset 0, flags [DF], proto SCTP (132), length 1292)
20+
192.168.5.2.36297 > 192.168.5.1.36413: sctp (1) [I-DATA] (E) [TSN: 2320017093] [SID: 0] [MID: 0] [FSN: 0]
21+
11 19:45:01.497595 IP (tos 0x2,ECT(0), ttl 64, id 4, offset 0, flags [DF], proto SCTP (132), length 40)
22+
192.168.5.1.36413 > 192.168.5.2.36297: sctp (1) [SHUTDOWN]
23+
12 19:45:01.497603 IP (tos 0x2,ECT(0), ttl 64, id 44216, offset 0, flags [DF], proto SCTP (132), length 36)
24+
192.168.5.2.36297 > 192.168.5.1.36413: sctp (1) [SHUTDOWN ACK]
25+
13 19:45:01.497608 IP (tos 0x2,ECT(0), ttl 64, id 5, offset 0, flags [DF], proto SCTP (132), length 36)
26+
192.168.5.1.36413 > 192.168.5.2.36297: sctp (1) [SHUTDOWN COMPLETE]

0 commit comments

Comments
 (0)