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