Skip to content

Commit c9cb765

Browse files
Yuxuan LuoCacheUseOnly
authored andcommitted
SCTP: Support RE-CONFIG chunk
Add support for printing RE-CONFIG chunk based on RFC6525 section3.1. Prints all optional parameters when `-vv` is set. Example: [RE-CONFIG] [OUT SSN RESET: REQ SEQ:, RES SEQ:, Last TSN:, SID 0 1]
1 parent a909b7e commit c9cb765

File tree

6 files changed

+352
-0
lines changed

6 files changed

+352
-0
lines changed

print-sctp.c

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
#define SCTP_ECN_CWR 0x0d
113113
#define SCTP_SHUTDOWN_COMPLETE 0x0e
114114
#define SCTP_I_DATA 0x40
115+
#define SCTP_RE_CONFIG 0x82
115116
#define SCTP_FORWARD_CUM_TSN 0xc0
116117
#define SCTP_RELIABLE_CNTL 0xc1
117118
#define SCTP_I_FORWARD_TSN 0xc2
@@ -133,6 +134,7 @@ static const struct tok sctp_chunkid_str[] = {
133134
{ SCTP_ECN_CWR, "ECN CWR" },
134135
{ SCTP_SHUTDOWN_COMPLETE, "SHUTDOWN COMPLETE" },
135136
{ SCTP_I_DATA, "I-DATA" },
137+
{ SCTP_RE_CONFIG, "RE-CONFIG" },
136138
{ SCTP_FORWARD_CUM_TSN, "FOR CUM TSN" },
137139
{ SCTP_RELIABLE_CNTL, "REL CTRL" },
138140
{ SCTP_I_FORWARD_TSN, "I-FORWARD-FSN" },
@@ -151,6 +153,14 @@ static const struct tok sctp_chunkid_str[] = {
151153
/* I-Forward-TSN Specific Flag */
152154
#define SCTP_I_FORWARD_UNORDERED 0x01
153155

156+
/* RE-CONFIG Parameters */
157+
#define OUT_SSN_RESET 13
158+
#define IN_SSN_RESET 14
159+
#define SSN_TSN_RESET 15
160+
#define RE_CONFIG_RES 16
161+
#define ADD_OUT_STREAM_REQ 17
162+
#define ADD_IN_STREAM_REQ 18
163+
154164
#define SCTP_ADDRMAX 60
155165

156166
#define CHAN_HP 6704
@@ -374,6 +384,33 @@ struct sctpIForwardEntry{
374384
nd_uint32_t MID;
375385
};
376386

387+
/* RE-CONFIG Parameters */
388+
struct sctpReConfigHdr{
389+
nd_uint16_t param_type;
390+
nd_uint16_t param_len;
391+
};
392+
393+
struct outGoingSSNReset{
394+
nd_uint32_t re_config_req;
395+
nd_uint32_t re_config_res;
396+
nd_uint32_t last_assigned_TSN;
397+
};
398+
399+
struct inGoingSSNReset{
400+
nd_uint32_t re_config_req;
401+
};
402+
403+
struct reConfigRes{
404+
nd_uint32_t res_seq_num;
405+
nd_uint32_t result;
406+
};
407+
408+
struct addStreamReq{
409+
nd_uint32_t res_seq_num;
410+
nd_uint16_t num_new_stream;
411+
nd_uint16_t reserved;
412+
};
413+
377414
struct sctpUnifiedDatagram{
378415
struct sctpChunkDesc uh;
379416
struct sctpDataPart dp;
@@ -390,6 +427,28 @@ struct sctpCWR{
390427
nd_uint32_t TSN_reduced_at;
391428
};
392429

430+
/* RE-CONFIG Parameters */
431+
static const struct tok RE_CONFIG_parameters[] = {
432+
{ OUT_SSN_RESET, "OUT SSN RESET" },
433+
{ IN_SSN_RESET, "IN SSN RESET" },
434+
{ SSN_TSN_RESET, "SSN/TSN Reset" },
435+
{ RE_CONFIG_RES, "RESP" },
436+
{ ADD_OUT_STREAM_REQ, "ADD OUT STREAM"},
437+
{ ADD_IN_STREAM_REQ, "ADD IN STREAM" },
438+
{ 0, NULL }
439+
};
440+
441+
static const struct tok results[] = {
442+
{ 0, "Success - Nothing to do" },
443+
{ 1, "Success - Performed" },
444+
{ 2, "Denied" },
445+
{ 3, "Error - Wrong SSN" },
446+
{ 4, "Error - Request already in progress" },
447+
{ 5, "Error - Bad Sequence Number" },
448+
{ 6, "In progress" },
449+
{ 0, NULL }
450+
};
451+
393452
static const struct tok ForCES_channels[] = {
394453
{ CHAN_HP, "ForCES HP" },
395454
{ CHAN_MP, "ForCES MP" },
@@ -872,6 +931,196 @@ sctp_print(netdissect_options *ndo,
872931
ND_PRINT("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
873932
GET_BE_U_4(dupTSN));
874933
}
934+
break;
935+
}
936+
case SCTP_RE_CONFIG:
937+
{
938+
const struct sctpReConfigHdr *param;
939+
uint16_t param_len, type;
940+
uint8_t padding_len;
941+
942+
sctpPacketLengthRemaining -= chunkLengthRemaining;
943+
944+
/* it's a padding if the remaining length is less than 4 */
945+
while (chunkLengthRemaining >= sizeof(uint32_t)) {
946+
947+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(*param));
948+
param = (const struct sctpReConfigHdr*)bp;
949+
type = GET_BE_U_2(param->param_type);
950+
param_len = GET_BE_U_2(param->param_len);
951+
padding_len = ((param_len+3) &~ 3) - param_len;
952+
ND_ICHECKMSG_ZU("parameter length", param_len, <, sizeof(*param));
953+
954+
ND_PRINT("[%s", tok2str(RE_CONFIG_parameters, NULL, type));
955+
956+
param_len -= sizeof(*param);
957+
chunkLengthRemaining -= sizeof(*param);
958+
bp += sizeof(*param);
959+
960+
ND_ICHECKMSG_U("chunk length", chunkLengthRemaining, <, param_len);
961+
962+
/* if verbose level < 2, stop and skip */
963+
if (ndo->ndo_vflag < 2) {
964+
ND_PRINT("]");
965+
966+
bp += param_len;
967+
chunkLengthRemaining -= param_len;
968+
/* skipping the parameter padding if there are more
969+
* parameters in the remaining length */
970+
if (chunkLengthRemaining > sizeof(uint32_t)) {
971+
bp += padding_len;
972+
chunkLengthRemaining -= padding_len;
973+
}
974+
975+
continue;
976+
}
977+
978+
switch (type) {
979+
case OUT_SSN_RESET:
980+
{
981+
uint16_t stream_num = 0;
982+
const struct outGoingSSNReset *content;
983+
984+
ND_ICHECKMSG_ZU("parameter length", param_len, <, sizeof(*content));
985+
986+
content = (const struct outGoingSSNReset*) bp;
987+
ND_PRINT(": REQ SEQ: %u, ", GET_BE_U_4(content->re_config_req));
988+
ND_PRINT("RES SEQ: %u, ", GET_BE_U_4(content->re_config_res));
989+
ND_PRINT("Last TSN: %u, ", GET_BE_U_4(content->last_assigned_TSN));
990+
991+
bp += sizeof(*content);
992+
param_len -= sizeof(*content);
993+
chunkLengthRemaining -= sizeof(*content);
994+
995+
ND_PRINT("SID");
996+
while (param_len > 0) {
997+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(stream_num));
998+
ND_ICHECKMSG_ZU("parameter length", param_len , <, sizeof(stream_num));
999+
stream_num = GET_BE_U_2(bp);
1000+
ND_PRINT(" %u", stream_num);
1001+
1002+
bp += sizeof(stream_num);
1003+
param_len -= sizeof(stream_num);
1004+
chunkLengthRemaining -= sizeof(stream_num);
1005+
}
1006+
ND_PRINT("]");
1007+
1008+
break;
1009+
}
1010+
case IN_SSN_RESET:
1011+
{
1012+
uint16_t stream_num = 0;
1013+
const struct inGoingSSNReset *content;
1014+
1015+
ND_ICHECKMSG_ZU("parameter length", param_len , <, sizeof(*content));
1016+
1017+
content = (const struct inGoingSSNReset*) bp;
1018+
ND_PRINT(": REQ SEQ: %u, ", GET_BE_U_4(content->re_config_req));
1019+
1020+
bp += sizeof(*content);
1021+
param_len -= sizeof(*content);
1022+
chunkLengthRemaining -= sizeof(*content);
1023+
1024+
ND_PRINT("SID");
1025+
while (param_len > 0) {
1026+
ND_ICHECKMSG_ZU("parameter length", param_len , <, sizeof(stream_num));
1027+
stream_num = GET_BE_U_2(bp);
1028+
ND_PRINT(" %u", stream_num);
1029+
1030+
bp += sizeof(stream_num);
1031+
param_len -= sizeof(stream_num);
1032+
chunkLengthRemaining -= sizeof(stream_num);
1033+
}
1034+
ND_PRINT("]");
1035+
1036+
break;
1037+
}
1038+
case SSN_TSN_RESET:
1039+
{
1040+
/* reuse inGoingSSNReset struct as their structure are the same*/
1041+
const struct inGoingSSNReset *content;
1042+
1043+
ND_ICHECKMSG_ZU("parameter length", param_len, <, sizeof(*content));
1044+
1045+
content = (const struct inGoingSSNReset*) bp;
1046+
ND_PRINT(": REQ SEQ: %u]", GET_BE_U_4(content->re_config_req));
1047+
1048+
bp += sizeof(*content);
1049+
chunkLengthRemaining -= sizeof(*content);
1050+
1051+
break;
1052+
}
1053+
case RE_CONFIG_RES:
1054+
{
1055+
uint32_t optional = 0;
1056+
const size_t optional_size = sizeof(optional);
1057+
const struct reConfigRes *content;
1058+
1059+
ND_ICHECKMSG_ZU("parameter length", param_len, <, sizeof(*content));
1060+
1061+
content = (const struct reConfigRes*) bp;
1062+
ND_PRINT(": REQ SEQ: %u, ", GET_BE_U_4(content->res_seq_num));
1063+
ND_PRINT("REQ: %s", tok2str(results, NULL, GET_BE_U_4(content->result)));
1064+
1065+
bp += sizeof(*content);
1066+
param_len -= sizeof(*content);
1067+
chunkLengthRemaining -= sizeof(*content);
1068+
1069+
if (0 == param_len) {
1070+
ND_PRINT("]");
1071+
break;
1072+
}
1073+
1074+
/* either both or none must be present */
1075+
ND_ICHECKMSG_ZU("parameter length", param_len, <, 2*optional_size);
1076+
optional = GET_BE_U_4(bp);
1077+
ND_PRINT(", Sender's TSN: %u", optional);
1078+
1079+
bp += optional_size;
1080+
param_len -= optional_size;
1081+
chunkLengthRemaining -= optional_size;
1082+
1083+
optional = GET_BE_U_4(bp);
1084+
ND_PRINT(", Receiver's Next TSN: %u] ", optional);
1085+
1086+
bp += optional_size;
1087+
chunkLengthRemaining -= optional_size;
1088+
1089+
break;
1090+
}
1091+
case ADD_OUT_STREAM_REQ:
1092+
case ADD_IN_STREAM_REQ:
1093+
{
1094+
const struct addStreamReq *content;
1095+
1096+
ND_ICHECKMSG_ZU("parameter length", param_len, <, sizeof(*content));
1097+
1098+
content = (const struct addStreamReq*) bp;
1099+
ND_PRINT(": REQ SEQ: %u, ", GET_BE_U_4(content->res_seq_num));
1100+
ND_PRINT("No. of new streams: %u] ", GET_BE_U_2(content->num_new_stream));
1101+
1102+
bp += sizeof(*content);
1103+
chunkLengthRemaining -= sizeof(*content);
1104+
1105+
break;
1106+
}
1107+
default:
1108+
{
1109+
bp += chunkLengthRemaining;
1110+
chunkLengthRemaining = 0;
1111+
break;
1112+
}
1113+
}
1114+
/* skipping the parameter padding if there are more parameters
1115+
* in the remaining length */
1116+
if (chunkLengthRemaining > sizeof(uint32_t)) {
1117+
bp += padding_len;
1118+
chunkLengthRemaining -= padding_len;
1119+
}
1120+
}
1121+
bp += chunkLengthRemaining;
1122+
chunkLengthRemaining = 0;
1123+
8751124
break;
8761125
}
8771126
default :

tests/TESTLIST

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ sctp-i-forward sctp-i-forward.pcap sctp-i-forward.out
5454
sctp-i-forward-v sctp-i-forward.pcap sctp-i-forward-v.out -v
5555
sctp-i-forward-vv sctp-i-forward.pcap sctp-i-forward-vv.out -vv
5656

57+
# RE-CONFIG tests
58+
sctp-re-config sctp-re-config.pcap sctp-re-config.out
59+
sctp-re-config-v sctp-re-config.pcap sctp-re-config-v.out -v
60+
sctp-re-config-vv sctp-re-config.pcap sctp-re-config-vv.out -vv
61+
5762
# BGP tests
5863
bgp_vpn_attrset bgp_vpn_attrset.pcap bgp_vpn_attrset.out -v
5964
mpbgp-linklocal-nexthop mpbgp-linklocal-nexthop.pcap mpbgp-linklocal-nexthop.out -v

tests/sctp-re-config-v.out

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
1 19:56:38.595332 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 92)
2+
192.168.5.1.58384 > 192.168.5.2.36297: sctp (1) [INIT] [init tag: 2670115933] [rwnd: 106496] [OS: 10] [MIS: 65535] [init TSN: 1593007960]
3+
2 19:56:38.595368 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.58384: sctp (1) [INIT ACK] [init tag: 2082750980] [rwnd: 106496] [OS: 5] [MIS: 5] [init TSN: 2238062072]
5+
3 19:56:38.595379 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 296)
6+
192.168.5.1.58384 > 192.168.5.2.36297: sctp (1) [COOKIE ECHO]
7+
4 19:56:38.595392 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.58384: sctp (1) [COOKIE ACK]
9+
5 19:56:38.595416 IP (tos 0x2,ECT(0), ttl 64, id 1, offset 0, flags [DF], proto SCTP (132), length 76)
10+
192.168.5.1.58384 > 192.168.5.2.36297: sctp (1) [RE-CONFIG] [OUT SSN RESET][IN SSN RESET]
11+
6 19:56:38.595421 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 76)
12+
192.168.5.2.36297 > 192.168.5.1.58384: sctp (1) [RE-CONFIG] [RESP], (2) [RE-CONFIG] [OUT SSN RESET]
13+
7 19:56:38.595426 IP (tos 0x2,ECT(0), ttl 64, id 2, offset 0, flags [DF], proto SCTP (132), length 48)
14+
192.168.5.1.58384 > 192.168.5.2.36297: sctp (1) [RE-CONFIG] [RESP]
15+
8 19:56:38.595434 IP (tos 0x2,ECT(0), ttl 64, id 3, offset 0, flags [DF], proto SCTP (132), length 60)
16+
192.168.5.1.58384 > 192.168.5.2.36297: sctp (1) [DATA] (B)(E) [TSN: 1593007960] [SID: 0] [SSEQ 0] [PPID 0x0]
17+
9 19:56:38.595440 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 48)
18+
192.168.5.2.36297 > 192.168.5.1.58384: sctp (1) [SACK] [cum ack 1593007960] [a_rwnd 106486] [#gap acks 0] [#dup tsns 0]
19+
10 19:56:40.359603 IP (tos 0x2,ECT(0), ttl 64, id 4, offset 0, flags [DF], proto SCTP (132), length 92)
20+
192.168.5.1.58384 > 192.168.5.4.36297: sctp (1) [HB REQ]
21+
11 19:56:40.359631 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 92)
22+
192.168.5.2.36297 > 192.168.5.1.58384: sctp (1) [HB ACK]
23+
12 19:56:42.055670 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 92)
24+
192.168.5.2.36297 > 192.168.5.3.58384: sctp (1) [HB REQ]
25+
13 19:56:42.055866 IP (tos 0x2,ECT(0), ttl 64, id 5, offset 0, flags [DF], proto SCTP (132), length 92)
26+
192.168.5.1.58384 > 192.168.5.2.36297: sctp (1) [HB ACK]
27+
14 19:56:51.811692 IP (tos 0x2,ECT(0), ttl 64, id 6, offset 0, flags [DF], proto SCTP (132), length 40)
28+
192.168.5.1.58384 > 192.168.5.2.36297: sctp (1) [SHUTDOWN]
29+
15 19:56:51.811707 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 36)
30+
192.168.5.2.36297 > 192.168.5.1.58384: sctp (1) [SHUTDOWN ACK]
31+
16 19:56:51.811712 IP (tos 0x2,ECT(0), ttl 64, id 7, offset 0, flags [DF], proto SCTP (132), length 36)
32+
192.168.5.1.58384 > 192.168.5.2.36297: sctp (1) [SHUTDOWN COMPLETE]

tests/sctp-re-config-vv.out

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
1 19:56:38.595332 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 92)
2+
192.168.5.1.58384 > 192.168.5.2.36297: sctp
3+
1) [INIT] [init tag: 2670115933] [rwnd: 106496] [OS: 10] [MIS: 65535] [init TSN: 1593007960]
4+
2 19:56:38.595368 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 348)
5+
192.168.5.2.36297 > 192.168.5.1.58384: sctp
6+
1) [INIT ACK] [init tag: 2082750980] [rwnd: 106496] [OS: 5] [MIS: 5] [init TSN: 2238062072]
7+
3 19:56:38.595379 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 296)
8+
192.168.5.1.58384 > 192.168.5.2.36297: sctp
9+
1) [COOKIE ECHO]
10+
4 19:56:38.595392 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 36)
11+
192.168.5.2.36297 > 192.168.5.1.58384: sctp
12+
1) [COOKIE ACK]
13+
5 19:56:38.595416 IP (tos 0x2,ECT(0), ttl 64, id 1, offset 0, flags [DF], proto SCTP (132), length 76)
14+
192.168.5.1.58384 > 192.168.5.2.36297: sctp
15+
1) [RE-CONFIG] [OUT SSN RESET: REQ SEQ: 1593007960, RES SEQ: 2238062071, Last TSN: 1593007959, SID 0 1 2 3][IN SSN RESET: REQ SEQ: 1593007961, SID 0 1 2 3]
16+
6 19:56:38.595421 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 76)
17+
192.168.5.2.36297 > 192.168.5.1.58384: sctp
18+
1) [RE-CONFIG] [RESP: REQ SEQ: 1593007960, REQ: Success - Performed]
19+
2) [RE-CONFIG] [OUT SSN RESET: REQ SEQ: 2238062072, RES SEQ: 1593007961, Last TSN: 2238062071, SID 0 1 2 3]
20+
7 19:56:38.595426 IP (tos 0x2,ECT(0), ttl 64, id 2, offset 0, flags [DF], proto SCTP (132), length 48)
21+
192.168.5.1.58384 > 192.168.5.2.36297: sctp
22+
1) [RE-CONFIG] [RESP: REQ SEQ: 2238062072, REQ: Success - Performed]
23+
8 19:56:38.595434 IP (tos 0x2,ECT(0), ttl 64, id 3, offset 0, flags [DF], proto SCTP (132), length 60)
24+
192.168.5.1.58384 > 192.168.5.2.36297: sctp
25+
1) [DATA] (B)(E) [TSN: 1593007960] [SID: 0] [SSEQ 0] [PPID 0x0] [Payload:
26+
0x0000: 7265 7365 7420 492f 4f00 reset.I/O.]
27+
9 19:56:38.595440 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 48)
28+
192.168.5.2.36297 > 192.168.5.1.58384: sctp
29+
1) [SACK] [cum ack 1593007960] [a_rwnd 106486] [#gap acks 0] [#dup tsns 0]
30+
10 19:56:40.359603 IP (tos 0x2,ECT(0), ttl 64, id 4, offset 0, flags [DF], proto SCTP (132), length 92)
31+
192.168.5.1.58384 > 192.168.5.4.36297: sctp
32+
1) [HB REQ]
33+
11 19:56:40.359631 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 92)
34+
192.168.5.2.36297 > 192.168.5.1.58384: sctp
35+
1) [HB ACK]
36+
12 19:56:42.055670 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 92)
37+
192.168.5.2.36297 > 192.168.5.3.58384: sctp
38+
1) [HB REQ]
39+
13 19:56:42.055866 IP (tos 0x2,ECT(0), ttl 64, id 5, offset 0, flags [DF], proto SCTP (132), length 92)
40+
192.168.5.1.58384 > 192.168.5.2.36297: sctp
41+
1) [HB ACK]
42+
14 19:56:51.811692 IP (tos 0x2,ECT(0), ttl 64, id 6, offset 0, flags [DF], proto SCTP (132), length 40)
43+
192.168.5.1.58384 > 192.168.5.2.36297: sctp
44+
1) [SHUTDOWN]
45+
15 19:56:51.811707 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 36)
46+
192.168.5.2.36297 > 192.168.5.1.58384: sctp
47+
1) [SHUTDOWN ACK]
48+
16 19:56:51.811712 IP (tos 0x2,ECT(0), ttl 64, id 7, offset 0, flags [DF], proto SCTP (132), length 36)
49+
192.168.5.1.58384 > 192.168.5.2.36297: sctp
50+
1) [SHUTDOWN COMPLETE]

0 commit comments

Comments
 (0)