Skip to content

Commit 66897e9

Browse files
Yuxuan Luofxlb
Yuxuan Luo
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 238d878 commit 66897e9

File tree

1 file changed

+246
-0
lines changed

1 file changed

+246
-0
lines changed

print-sctp.c

Lines changed: 246 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,27 @@ 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+
};
450+
393451
static const struct tok ForCES_channels[] = {
394452
{ CHAN_HP, "ForCES HP" },
395453
{ CHAN_MP, "ForCES MP" },
@@ -868,6 +926,194 @@ sctp_print(netdissect_options *ndo,
868926
ND_PRINT("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
869927
GET_BE_U_4(dupTSN));
870928
}
929+
break;
930+
}
931+
case SCTP_RE_CONFIG:
932+
{
933+
const struct sctpReConfigHdr *param;
934+
uint16_t param_len, type;
935+
uint8_t padding_len;
936+
937+
sctpPacketLengthRemaining -= chunkLengthRemaining;
938+
939+
while (0 != chunkLengthRemaining) {
940+
/* it's a padding if the remaining length is less than 4 */
941+
if (sizeof(uint32_t) >= chunkLengthRemaining) {
942+
chunkLengthRemaining = 0;
943+
break;
944+
}
945+
946+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(*param));
947+
param = (const struct sctpReConfigHdr*)bp;
948+
param_len = GET_BE_U_2(param->param_len);
949+
type = GET_BE_U_2(param->param_type);
950+
padding_len = param_len % 4;
951+
952+
ND_PRINT("[%s", tok2str(RE_CONFIG_parameters, NULL, type));
953+
954+
param_len -= sizeof(*param);
955+
chunkLengthRemaining -= sizeof(*param);
956+
bp += sizeof(*param);
957+
if (ndo->ndo_vflag < 2) { /* if verbose level < 2, stop and skip */
958+
ND_PRINT("]");
959+
960+
ND_ICHECKMSG_U("chunk length", chunkLengthRemaining, <, param_len);
961+
bp += param_len;
962+
chunkLengthRemaining -= param_len;
963+
/* it's a parameter padding if there are more parameters in the remaining length */
964+
if (chunkLengthRemaining > 4)
965+
bp += padding_len;
966+
967+
continue;
968+
}
969+
970+
switch (type) {
971+
case OUT_SSN_RESET:
972+
{
973+
uint16_t stream_num = 0;
974+
const struct outGoingSSNReset *content;
975+
976+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(*content));
977+
978+
content = (const struct outGoingSSNReset*) bp;
979+
ND_PRINT(": REQ SEQ: %u, ", GET_BE_U_4(content->re_config_req));
980+
ND_PRINT("RES SEQ: %u, ", GET_BE_U_4(content->re_config_res));
981+
ND_PRINT("Last TSN: %u, ", GET_BE_U_4(content->last_assigned_TSN));
982+
983+
bp += sizeof(*content);
984+
param_len -= sizeof(*content);
985+
chunkLengthRemaining -= sizeof(*content);
986+
987+
ND_PRINT("SID");
988+
while (0 != param_len) {
989+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(stream_num));
990+
stream_num = GET_BE_U_2(bp);
991+
ND_PRINT(" %u", stream_num);
992+
993+
bp += sizeof(stream_num);
994+
param_len -= sizeof(stream_num);
995+
chunkLengthRemaining -= sizeof(stream_num);
996+
}
997+
ND_PRINT("]");
998+
999+
break;
1000+
}
1001+
case IN_SSN_RESET:
1002+
{
1003+
uint16_t stream_num = 0;
1004+
const struct inGoingSSNReset *content;
1005+
1006+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(*content));
1007+
1008+
content = (const struct inGoingSSNReset*) bp;
1009+
ND_PRINT(": REQ SEQ: %u, ", GET_BE_U_4(content->re_config_req));
1010+
1011+
bp += sizeof(*content);
1012+
param_len -= sizeof(*content);
1013+
chunkLengthRemaining -= sizeof(*content);
1014+
1015+
ND_PRINT("SID");
1016+
while (0 != param_len) {
1017+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(stream_num));
1018+
stream_num = GET_BE_U_2(bp);
1019+
ND_PRINT(" %u", stream_num);
1020+
1021+
bp += sizeof(stream_num);
1022+
param_len -= sizeof(stream_num);
1023+
chunkLengthRemaining -= sizeof(stream_num);
1024+
}
1025+
ND_PRINT("]");
1026+
1027+
break;
1028+
}
1029+
case SSN_TSN_RESET:
1030+
{
1031+
const struct inGoingSSNReset *content;
1032+
1033+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(*content));
1034+
1035+
content = (const struct inGoingSSNReset*) bp;
1036+
ND_PRINT(": REQ SEQ: %u]", GET_BE_U_4(content->re_config_req));
1037+
1038+
bp += sizeof(*content);
1039+
chunkLengthRemaining -= sizeof(*content);
1040+
1041+
break;
1042+
}
1043+
case RE_CONFIG_RES:
1044+
{
1045+
uint32_t optional = 0;
1046+
const size_t optional_size = sizeof(optional);
1047+
const struct reConfigRes *content;
1048+
1049+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(*content));
1050+
1051+
content = (const struct reConfigRes*) bp;
1052+
ND_PRINT(": REQ SEQ: %u, ", GET_BE_U_4(content->res_seq_num));
1053+
ND_PRINT("REQ: %s", tok2str(results, NULL, GET_BE_U_4(content->result)));
1054+
1055+
bp += sizeof(*content);
1056+
param_len -= sizeof(*content);
1057+
chunkLengthRemaining -= sizeof(*content);
1058+
1059+
if (0 == param_len) {
1060+
ND_PRINT("]");
1061+
break;
1062+
}
1063+
1064+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, optional_size);
1065+
optional = GET_BE_U_4(bp);
1066+
ND_PRINT(", Sender's TSN: %u", optional);
1067+
1068+
bp += optional_size;
1069+
param_len -= optional_size;
1070+
chunkLengthRemaining -= optional_size;
1071+
1072+
if (0 == param_len) {
1073+
ND_PRINT("]");
1074+
break;
1075+
}
1076+
1077+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, optional_size);
1078+
optional = GET_BE_U_4(bp);
1079+
ND_PRINT(", Receiver's Next TSN: %u] ", optional);
1080+
1081+
bp += optional_size;
1082+
param_len -= optional_size;
1083+
chunkLengthRemaining -= optional_size;
1084+
1085+
break;
1086+
}
1087+
case ADD_OUT_STREAM_REQ:
1088+
case ADD_IN_STREAM_REQ:
1089+
{
1090+
const struct addStreamReq *content;
1091+
1092+
ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining, <, sizeof(*content));
1093+
1094+
content = (const struct addStreamReq*) bp;
1095+
ND_PRINT(": REQ SEQ: %u, ", GET_BE_U_4(content->res_seq_num));
1096+
ND_PRINT("No. of new streams: %u] ", GET_BE_U_2(content->num_new_stream));
1097+
1098+
bp += sizeof(*content);
1099+
param_len -= sizeof(*content);
1100+
chunkLengthRemaining -= sizeof(*content);
1101+
1102+
break;
1103+
}
1104+
default:
1105+
{
1106+
bp += chunkLengthRemaining;
1107+
chunkLengthRemaining = 0;
1108+
break;
1109+
}
1110+
}
1111+
1112+
/* it's a parameter padding if there are more parameters in the remaining length */
1113+
if (chunkLengthRemaining > 4)
1114+
bp += padding_len;
1115+
}
1116+
8711117
break;
8721118
}
8731119
default :

0 commit comments

Comments
 (0)