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 sctpAsconfParamRes {
440+ nd_uint16_t type ;
441+ nd_uint16_t length ;
442+ nd_uint32_t CID ;
443+ };
444+
445+ struct sctpASCONF {
446+ nd_uint32_t seq_num ;
447+ union {
448+ struct sctpV4IpAddress ipv4 ;
449+ struct sctpV6IpAddress ipv6 ;
450+ } addr ;
451+ };
452+
453+ struct sctpASCONF_ACK {
454+ nd_uint32_t seq_num ;
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" },
@@ -1120,6 +1192,157 @@ sctp_print(netdissect_options *ndo,
11201192 bp += chunkLengthRemaining ;
11211193 chunkLengthRemaining = 0 ;
11221194
1195+ break ;
1196+ }
1197+ case SCTP_ASCONF :
1198+ {
1199+ const struct sctpASCONF * content ;
1200+ const struct sctpAsconfParam * param ;
1201+ size_t length ;
1202+ uint16_t param_len ;
1203+
1204+ /* Should be at least longer than the length of IPv4 typed parameter*/
1205+ length = sizeof (nd_uint32_t ) + sizeof (struct sctpV4IpAddress );
1206+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , length );
1207+ content = (const struct sctpASCONF * ) bp ;
1208+ ND_PRINT ("[SEQ: %u, " , GET_BE_U_4 (content -> seq_num ));
1209+
1210+ if (GET_BE_U_2 (content -> addr .ipv4 .p .paramType ) == 5 ) { /* IPv4 */
1211+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , length );
1212+ ND_PRINT ("ADDR: %s] " , GET_IPADDR_STRING (content -> addr .ipv4 .ipAddress ));
1213+ } else if (GET_BE_U_2 (content -> addr .ipv6 .p .paramType ) == 6 ) { /* IPv6 */
1214+ length = sizeof (nd_uint32_t ) + sizeof (struct sctpV6IpAddress );
1215+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , length );
1216+ ND_PRINT ("ADDR: %s] " , GET_IP6ADDR_STRING (content -> addr .ipv6 .ipAddress ));
1217+ } else {
1218+ length = sizeof (nd_uint32_t ) + GET_BE_U_2 (content -> addr .ipv4 .p .paramLength );
1219+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , length );
1220+ ND_PRINT ("ADDR: bogus address type]" );
1221+ }
1222+ bp += length ;
1223+ chunkLengthRemaining -= length ;
1224+ sctpPacketLengthRemaining -= length ;
1225+
1226+ while (0 != chunkLengthRemaining ) {
1227+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , sizeof (uint32_t )); /* ensure param_len can be extracted */
1228+ param = (const struct sctpAsconfParam * ) bp ;
1229+ param_len = GET_BE_U_2 (param -> length );
1230+ ND_ICHECKMSG_ZU ("parameter length" , param_len , < , sizeof (uint16_t ));
1231+
1232+ ND_ICHECKMSG_U ("chunk length" , chunkLengthRemaining , < , param_len );
1233+ bp += param_len ;
1234+ chunkLengthRemaining -= param_len ;
1235+ sctpPacketLengthRemaining -= param_len ;
1236+
1237+ ND_PRINT ("[%s" , tok2str (asconfigParams , NULL , GET_BE_U_2 (param -> type )));
1238+
1239+ if (ndo -> ndo_vflag >= 2 ) {
1240+ ND_PRINT (": C-ID: %u, " , GET_BE_U_4 (param -> CID ));
1241+ if (GET_BE_U_2 (param -> addr .ipv4 .p .paramType ) == 5 ) { /* IPv4 */
1242+ length = sizeof (nd_uint32_t ) + sizeof (struct sctpV4IpAddress );
1243+ ND_ICHECKMSG_ZU ("param length" , param_len , < , length );
1244+ ND_PRINT ("ADDR: %s] " , GET_IPADDR_STRING (param -> addr .ipv4 .ipAddress ));
1245+ } else if (GET_BE_U_2 (param -> addr .ipv4 .p .paramType ) == 6 ) { /* IPv6 */
1246+ length = sizeof (nd_uint32_t ) + sizeof (struct sctpV6IpAddress );
1247+ ND_ICHECKMSG_ZU ("param length" , param_len , < , length );
1248+ ND_PRINT ("ADDR: %s] " , GET_IP6ADDR_STRING (param -> addr .ipv6 .ipAddress ));
1249+ } else {
1250+ ND_PRINT ("ADDR: bogus address type]" );
1251+ }
1252+ } else {
1253+ ND_PRINT ("]" );
1254+ }
1255+ }
1256+ break ;
1257+ }
1258+ case SCTP_ASCONF_ACK :
1259+ {
1260+ const struct sctpASCONF_ACK * content ;
1261+ const struct sctpAsconfParamRes * param ;
1262+ uint16_t param_len ;
1263+
1264+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , sizeof (* content ));
1265+ content = (const struct sctpASCONF_ACK * ) bp ;
1266+ ND_PRINT ("[SEQ: %u] " , GET_BE_U_4 (content -> seq_num ));
1267+
1268+ bp += sizeof (* content );
1269+ chunkLengthRemaining -= sizeof (* content );
1270+ sctpPacketLengthRemaining -= sizeof (* content );
1271+
1272+ while (0 != chunkLengthRemaining ) {
1273+ ND_ICHECKMSG_ZU ("chunk length" , chunkLengthRemaining , < , sizeof (struct sctpAsconfParamRes ));
1274+ param = (const struct sctpAsconfParamRes * ) bp ;
1275+ param_len = GET_BE_U_2 (param -> length );
1276+ ND_ICHECKMSG_ZU ("parameter length" , param_len , < , sizeof (struct sctpAsconfParamRes ));
1277+ ND_ICHECKMSG_U ("chunk length" , chunkLengthRemaining , < , param_len );
1278+
1279+ ND_PRINT ("[%s" , tok2str (asconfigParams , NULL , GET_BE_U_2 (param -> type )));
1280+ sctpPacketLengthRemaining -= param_len ;
1281+
1282+ /* print payload only when vflag >= 2 */
1283+ if (ndo -> ndo_vflag < 2 ) {
1284+ ND_PRINT ("] " );
1285+ bp += param_len ;
1286+ chunkLengthRemaining -= param_len ;
1287+ continue ;
1288+ }
1289+
1290+ switch (GET_BE_U_2 (param -> type )) {
1291+ case ERR_CAUSE_INDIC :
1292+ {
1293+ uint16_t cause_len ;
1294+ const struct sctpOpErrorCause * err_cause ;
1295+
1296+ ND_PRINT (": C-ID: %u " , GET_BE_U_4 (param -> CID ));
1297+ bp += sizeof (struct sctpAsconfParamRes );
1298+ param_len -= sizeof (struct sctpAsconfParamRes );
1299+ chunkLengthRemaining -= sizeof (struct sctpAsconfParamRes );
1300+ if (0 == param_len ) {
1301+ ND_PRINT ("] " );
1302+ break ;
1303+ }
1304+
1305+ /* check against ERROR length */
1306+ ND_ICHECKMSG_ZU ("chunk length" , param_len , < , sizeof (uint32_t ));
1307+ bp += sizeof (uint16_t );
1308+ ND_ICHECKMSG_U ("param length" , param_len , < , GET_BE_U_2 (bp ));
1309+ bp += sizeof (uint16_t );
1310+ param_len -= sizeof (uint32_t );
1311+ chunkLengthRemaining -= sizeof (uint32_t );
1312+
1313+ while (0 != param_len ) {
1314+ ND_ICHECKMSG_ZU ("param length" , param_len , < , sizeof (* err_cause ));
1315+ err_cause = (const struct sctpOpErrorCause * ) bp ;
1316+ cause_len = GET_BE_U_2 (err_cause -> causeLen );
1317+ ND_ICHECKMSG_U ("cause length" , cause_len , > , param_len );
1318+ ND_ICHECKMSG_ZU ("cause length" , cause_len , < , sizeof (* err_cause ));
1319+ ND_PRINT ("%s, " , tok2str (causeCode , NULL , GET_BE_U_2 (err_cause -> cause )));
1320+
1321+ bp += cause_len ;
1322+ param_len -= cause_len ;
1323+ chunkLengthRemaining -= cause_len ;
1324+ }
1325+ ND_PRINT ("] " );
1326+ break ;
1327+ }
1328+ case SUCCESS_INDIC :
1329+ {
1330+ ND_PRINT (": C-ID: %u " , GET_BE_U_4 (param -> CID ));
1331+ bp += sizeof (struct sctpAsconfParamRes );
1332+ param_len -= sizeof (struct sctpAsconfParamRes );
1333+ chunkLengthRemaining -= sizeof (struct sctpAsconfParamRes );
1334+ break ;
1335+ }
1336+ default :
1337+ {
1338+ ND_PRINT ("Unknown parameter] " );
1339+ bp += param_len ;
1340+ chunkLengthRemaining -= param_len ;
1341+ param_len -= param_len ;
1342+ break ;
1343+ }
1344+ }
1345+ }
11231346 break ;
11241347 }
11251348 default :
0 commit comments