112112#define SCTP_ECN_CWR 0x0d
113113#define SCTP_SHUTDOWN_COMPLETE 0x0e
114114#define SCTP_I_DATA 0x40
115+ #define SCTP_ASCONF_ACK 0x80
115116#define SCTP_RE_CONFIG 0x82
116117#define SCTP_FORWARD_CUM_TSN 0xc0
117- #define SCTP_RELIABLE_CNTL 0xc1
118+ #define SCTP_ASCONF 0xc1
118119#define SCTP_I_FORWARD_TSN 0xc2
119120
120121static const struct tok sctp_chunkid_str [] = {
@@ -136,7 +137,8 @@ static const struct tok sctp_chunkid_str[] = {
136137 { SCTP_I_DATA , "I-DATA" },
137138 { SCTP_RE_CONFIG , "RE-CONFIG" },
138139 { SCTP_FORWARD_CUM_TSN , "FOR CUM TSN" },
139- { SCTP_RELIABLE_CNTL , "REL CTRL" },
140+ { SCTP_ASCONF , "ASCONF" },
141+ { SCTP_ASCONF_ACK , "ASCONF-ACK" },
140142 { SCTP_I_FORWARD_TSN , "I-FORWARD-FSN" },
141143 { 0 , NULL }
142144};
@@ -163,6 +165,18 @@ static const struct tok sctp_chunkid_str[] = {
163165
164166#define SCTP_ADDRMAX 60
165167
168+ /* ASCONF Parameters*/
169+ /* - used in INIT/ACK chunk */
170+ #define SET_PRI_ADDR 0xC004
171+ #define ADAPT_LAYER_INDIC 0xC006
172+ #define SUPPORTED_EXT 0x8008
173+ /* - used in ASCONF param */
174+ #define ADD_IP_ADDR 0xC001
175+ #define DEL_IP_ADDR 0xC002
176+ /* - used in ASCONF response */
177+ #define ERR_CAUSE_INDIC 0xC003
178+ #define SUCCESS_INDIC 0xC005
179+
166180#define CHAN_HP 6704
167181#define CHAN_MP 6705
168182#define CHAN_LP 6706
@@ -411,6 +425,35 @@ struct addStreamReq{
411425 nd_uint16_t reserved ;
412426};
413427
428+ /* ASCONF parameters */
429+ struct sctpAsconfParam {
430+ nd_uint16_t type ;
431+ nd_uint16_t length ;
432+ nd_uint32_t CID ;
433+ union {
434+ struct sctpV4IpAddress ipv4 ;
435+ struct sctpV6IpAddress ipv6 ;
436+ } addr ;
437+ };
438+
439+ struct sctpASCONF {
440+ nd_uint32_t seq_num ;
441+ union {
442+ struct sctpV4IpAddress ipv4 ;
443+ struct sctpV6IpAddress ipv6 ;
444+ } addr ;
445+ };
446+
447+ struct sctpASCONF_ACK {
448+ nd_uint32_t seq_num ;
449+ };
450+
451+ struct sctpErrParam {
452+ nd_uint8_t type ;
453+ nd_uint8_t flags ;
454+ nd_uint16_t length ;
455+ };
456+
414457struct sctpUnifiedDatagram {
415458 struct sctpChunkDesc uh ;
416459 struct sctpDataPart dp ;
@@ -449,6 +492,35 @@ static const struct tok results[] = {
449492 { 0 , NULL }
450493};
451494
495+ /* ASCONF tokens */
496+ static const struct tok asconfigParams [] = {
497+ { SET_PRI_ADDR , "SET PRIM ADDR" },
498+ { ADAPT_LAYER_INDIC , "Adaptation Layer Indication" },
499+ { SUPPORTED_EXT , "Supported Extensions" },
500+ { ADD_IP_ADDR , "ADD ADDR" },
501+ { DEL_IP_ADDR , "DEL ADDR" },
502+ { ERR_CAUSE_INDIC , "ERR" },
503+ { SUCCESS_INDIC , "SUCCESS" },
504+ { 0 , NULL }
505+ };
506+
507+ static const struct tok causeCode [] = {
508+ { 1 , "Invalid Stream Identifier" },
509+ { 2 , "Missing Mandatory Parameter" },
510+ { 3 , "Stale Cookie Error" },
511+ { 4 , "Out of Resource" },
512+ { 5 , "Unresolvable Address" },
513+ { 6 , "Unrecognized Chunk Type" },
514+ { 7 , "Invalid Mandatory Parameter" },
515+ { 8 , "Unrecognized Parameters" },
516+ { 9 , "No User Data" },
517+ { 10 , "Cookie Received While Shutting Down" },
518+ { 11 , "Restart of an Association with New Addresses" },
519+ { 12 , "User Initiated Abort" },
520+ { 13 , "Protocol Violation" },
521+ { 0 , NULL }
522+ };
523+
452524static const struct tok ForCES_channels [] = {
453525 { CHAN_HP , "ForCES HP" },
454526 { CHAN_MP , "ForCES MP" },
@@ -1115,6 +1187,150 @@ sctp_print(netdissect_options *ndo,
11151187 bp += padding_len ;
11161188 }
11171189
1190+ break ;
1191+ }
1192+ case SCTP_ASCONF :
1193+ {
1194+ const struct sctpASCONF * content ;
1195+ const struct sctpAsconfParam * param ;
1196+ size_t length ;
1197+ uint16_t param_len ;
1198+
1199+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , sizeof (* content ));
1200+ content = (const struct sctpASCONF * ) bp ;
1201+ ND_PRINT ("[SEQ: %u, " , GET_BE_U_4 (content -> seq_num ));
1202+
1203+ if (GET_BE_U_2 (content -> addr .ipv4 .p .paramType ) == 5 ) { /* IPv4 */
1204+ length = sizeof (nd_uint32_t ) + sizeof (struct sctpV4IpAddress );
1205+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , length );
1206+ ND_PRINT ("ADDR: %s] " , GET_IPADDR_STRING (content -> addr .ipv4 .ipAddress ));
1207+ } else if (GET_BE_U_2 (content -> addr .ipv6 .p .paramType ) == 6 ) { /* IPv6 */
1208+ length = sizeof (nd_uint32_t ) + sizeof (struct sctpV6IpAddress );
1209+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , length );
1210+ ND_PRINT ("ADDR: %s] " , GET_IP6ADDR_STRING (content -> addr .ipv4 .ipAddress ));
1211+ } else {
1212+ length = sizeof (nd_uint32_t ) + GET_BE_U_2 (content -> addr .ipv4 .p .paramLength );
1213+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , length );
1214+ ND_PRINT ("ADDR: bogus address type]" );
1215+ }
1216+ bp += length ;
1217+ chunkLengthRemaining -= length ;
1218+ sctpPacketLengthRemaining -= length ;
1219+
1220+ while (0 != chunkLengthRemaining ) {
1221+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , sizeof (uint32_t )); /* ensure param_len can be extracted */
1222+ param = (const struct sctpAsconfParam * ) bp ;
1223+ param_len = GET_BE_U_2 (param -> length );
1224+
1225+ ND_ICHECKMSG_U ("chunk length" , chunkLengthRemaining , < , param_len );
1226+ bp += param_len ;
1227+ chunkLengthRemaining -= param_len ;
1228+ sctpPacketLengthRemaining -= param_len ;
1229+
1230+ ND_PRINT ("[%s" , tok2str (asconfigParams , NULL , GET_BE_U_2 (param -> type )));
1231+
1232+ if (ndo -> ndo_vflag >= 2 ) {
1233+ ND_PRINT (": C-ID: %u, " , GET_BE_U_4 (param -> CID ));
1234+ if (GET_BE_U_2 (param -> addr .ipv4 .p .paramType ) == 5 ) { /* IPv4 */
1235+ length = sizeof (nd_uint32_t ) + sizeof (struct sctpV4IpAddress );
1236+ ND_ICHECKMSG_ZU ("param length" , param_len , < , length );
1237+ ND_PRINT ("ADDR: %s] " , GET_IPADDR_STRING (param -> addr .ipv4 .ipAddress ));
1238+ } else if (GET_BE_U_2 (param -> addr .ipv4 .p .paramType ) == 6 ) { /* IPv6 */
1239+ length = sizeof (nd_uint32_t ) + sizeof (struct sctpV6IpAddress );
1240+ ND_ICHECKMSG_ZU ("param length" , param_len , < , length );
1241+ ND_PRINT ("ADDR: %s] " , GET_IP6ADDR_STRING (param -> addr .ipv6 .ipAddress ));
1242+ } else {
1243+ ND_PRINT ("ADDR: bogus address type]" );
1244+ }
1245+ } else {
1246+ ND_PRINT ("]" );
1247+ }
1248+ }
1249+ break ;
1250+ }
1251+ case SCTP_ASCONF_ACK :
1252+ {
1253+ const struct sctpASCONF_ACK * content ;
1254+ const struct sctpAsconfParam * header ;
1255+ uint16_t param_len ;
1256+
1257+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , sizeof (* content ));
1258+ content = (const struct sctpASCONF_ACK * ) bp ;
1259+ ND_PRINT ("[SEQ: %u] " , GET_BE_U_4 (content -> seq_num ));
1260+
1261+ bp += sizeof (* content );
1262+ chunkLengthRemaining -= sizeof (* content );
1263+ sctpPacketLengthRemaining -= sizeof (* content );
1264+
1265+ while (0 != chunkLengthRemaining ) {
1266+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , sizeof (* header ));
1267+ header = (const struct sctpAsconfParam * ) bp ;
1268+ param_len = GET_BE_U_2 (header -> length );
1269+ ND_ICHECKMSG_U ("chunk length" , chunkLengthRemaining , < , param_len );
1270+
1271+ ND_PRINT ("[%s" , tok2str (asconfigParams , NULL , GET_BE_U_2 (header -> type )));
1272+
1273+ /* print payload only when vflag >= 2 */
1274+ if (ndo -> ndo_vflag < 2 ) {
1275+ ND_PRINT ("] " );
1276+ bp += param_len ;
1277+ chunkLengthRemaining -= param_len ;
1278+ sctpPacketLengthRemaining -= param_len ;
1279+ continue ;
1280+ }
1281+
1282+ bp += sizeof (* header );
1283+ chunkLengthRemaining -= sizeof (* header );
1284+ sctpPacketLengthRemaining -= sizeof (* header );
1285+
1286+ switch (GET_BE_U_2 (header -> type )) {
1287+ case ERR_CAUSE_INDIC :
1288+ {
1289+ const struct sctpErrParam * errHdr ;
1290+ const struct sctpOpErrorCause * err_cause ;
1291+ uint16_t param_remaining ;
1292+ uint16_t cause_len ;
1293+
1294+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , sizeof (struct sctpErrParam ));
1295+ errHdr = (const struct sctpErrParam * ) bp ;
1296+ param_remaining = GET_BE_U_2 (errHdr -> length );
1297+ ND_ICHECKMSG_U ("chunk length" , chunkLengthRemaining , < , param_remaining );
1298+
1299+ bp += sizeof (* errHdr );
1300+ chunkLengthRemaining -= sizeof (* errHdr );
1301+ sctpPacketLengthRemaining -= sizeof (* errHdr );
1302+
1303+ ND_PRINT (": " );
1304+ while (0 != param_remaining ) {
1305+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , sizeof (* err_cause ));
1306+ err_cause = (const struct sctpOpErrorCause * ) bp ;
1307+ ND_PRINT (" %s, " , tok2str (causeCode , NULL , GET_BE_U_2 (err_cause -> cause )));
1308+
1309+ cause_len = GET_BE_U_2 (err_cause -> causeLen );
1310+ ND_ICHECKMSG_ZU ("cause length" , cause_len , < , sizeof (* err_cause ));
1311+ ND_ICHECKMSG_U ("param length" , param_remaining , < , cause_len );
1312+ bp += cause_len ;
1313+ param_remaining -= cause_len ;
1314+ chunkLengthRemaining -= cause_len ;
1315+ sctpPacketLengthRemaining -= cause_len ;
1316+ }
1317+ ND_PRINT ("] " );
1318+ break ;
1319+ }
1320+ case SUCCESS_INDIC :
1321+ {
1322+ ND_PRINT (": C-ID %u] " , GET_BE_U_4 (bp ));
1323+ bp += sizeof (uint32_t );
1324+ break ;
1325+ }
1326+ default :
1327+ {
1328+ ND_PRINT ("Unknown parameter] " );
1329+ bp += (param_len - sizeof (* header ));
1330+ break ;
1331+ }
1332+ }
1333+ }
11181334 break ;
11191335 }
11201336 default :
0 commit comments