@@ -353,6 +353,142 @@ icmp_tstamp_print(u_int tstamp)
353353 return buf ;
354354}
355355
356+ static int
357+ print_icmp_multipart_ext_object (netdissect_options * ndo , const uint8_t * obj_tptr )
358+ {
359+ u_int obj_tlen , obj_class_num , obj_ctype ;
360+ const struct icmp_multipart_ext_object_header_t * icmp_multipart_ext_object_header ;
361+
362+ icmp_multipart_ext_object_header = (const struct icmp_multipart_ext_object_header_t * )obj_tptr ;
363+ obj_tlen = GET_BE_U_2 (icmp_multipart_ext_object_header -> length );
364+ obj_class_num = GET_U_1 (icmp_multipart_ext_object_header -> class_num );
365+ obj_ctype = GET_U_1 (icmp_multipart_ext_object_header -> ctype );
366+ obj_tptr += sizeof (struct icmp_multipart_ext_object_header_t );
367+
368+ ND_PRINT ("\n\t %s (%u), Class-Type: %u, length %u" ,
369+ tok2str (icmp_multipart_ext_obj_values ,"unknown" ,obj_class_num ),
370+ obj_class_num ,
371+ obj_ctype ,
372+ obj_tlen );
373+
374+ /* infinite loop protection */
375+ if ((obj_class_num == 0 ) ||
376+ (obj_tlen < sizeof (struct icmp_multipart_ext_object_header_t ))) {
377+ return -1 ;
378+ }
379+ obj_tlen -= sizeof (struct icmp_multipart_ext_object_header_t );
380+
381+ switch (obj_class_num ) {
382+ case MPLS_STACK_ENTRY_OBJECT_CLASS :
383+ switch (obj_ctype ) {
384+ case 1 :
385+ {
386+ uint32_t raw_label ;
387+
388+ raw_label = GET_BE_U_4 (obj_tptr );
389+ ND_PRINT ("\n\t label %u, tc %u" , MPLS_LABEL (raw_label ), MPLS_TC (raw_label ));
390+ if (MPLS_STACK (raw_label ))
391+ ND_PRINT (", [S]" );
392+ ND_PRINT (", ttl %u" , MPLS_TTL (raw_label ));
393+ break ;
394+ }
395+ default :
396+ print_unknown_data (ndo , obj_tptr , "\n\t " , obj_tlen );
397+ }
398+ break ;
399+
400+ case INTERFACE_INFORMATION_OBJECT_CLASS :
401+ {
402+ /*
403+ Ctype in a INTERFACE_INFORMATION_OBJECT_CLASS object:
404+
405+ Bit 0 1 2 3 4 5 6 7
406+ +-------+-------+-------+-------+-------+-------+-------+-------+
407+ | Interface Role| Rsvd1 | Rsvd2 |ifIndex| IPAddr| name | MTU |
408+ +-------+-------+-------+-------+-------+-------+-------+-------+
409+ */
410+ const uint8_t * offset ;
411+ u_int interface_role , if_index_flag , ipaddr_flag , name_flag , mtu_flag ;
412+
413+ interface_role = (obj_ctype & 0xc0 ) >> 6 ;
414+ if_index_flag = (obj_ctype & 0x8 ) >> 3 ;
415+ ipaddr_flag = (obj_ctype & 0x4 ) >> 2 ;
416+ name_flag = (obj_ctype & 0x2 ) >> 1 ;
417+ mtu_flag = (obj_ctype & 0x1 );
418+
419+ ND_PRINT ("\n\t Interface Role: %s" ,
420+ tok2str (icmp_interface_information_role_values ,
421+ "an unknown interface role" ,interface_role ));
422+
423+ offset = obj_tptr ;
424+
425+ if (if_index_flag ) {
426+ ND_PRINT ("\n\t Interface Index: %u" , GET_BE_U_4 (offset ));
427+ offset += 4 ;
428+ }
429+ if (ipaddr_flag ) {
430+ const struct icmp_interface_information_ipaddr_subobject_t * ipaddr_subobj ;
431+
432+ ND_PRINT ("\n\t IP Address sub-object: " );
433+ ipaddr_subobj = (const struct icmp_interface_information_ipaddr_subobject_t * ) offset ;
434+ switch (GET_BE_U_2 (ipaddr_subobj -> afi )) {
435+ case 1 :
436+ ND_PRINT ("%s" , GET_IPADDR_STRING (ipaddr_subobj -> ip_addr ));
437+ offset += 4 ;
438+ break ;
439+ case 2 :
440+ ND_PRINT ("%s" , GET_IP6ADDR_STRING (ipaddr_subobj -> ip_addr ));
441+ offset += 16 ;
442+ break ;
443+ default :
444+ ND_PRINT ("Unknown Address Family Identifier" );
445+ return -1 ;
446+ }
447+ offset += 4 ;
448+ }
449+ if (name_flag ) {
450+ uint8_t inft_name_length_field ;
451+ const struct icmp_interface_information_ifname_subobject_t * ifname_subobj ;
452+
453+ ifname_subobj = (const struct icmp_interface_information_ifname_subobject_t * ) offset ;
454+ inft_name_length_field = GET_U_1 (ifname_subobj -> length );
455+ ND_PRINT ("\n\t Interface Name" );
456+ if (inft_name_length_field == 0 ) {
457+ ND_PRINT (" [length %u]" , inft_name_length_field );
458+ nd_print_invalid (ndo );
459+ break ;
460+ }
461+ if (inft_name_length_field % 4 != 0 ) {
462+ ND_PRINT (" [length %u != N x 4]" , inft_name_length_field );
463+ nd_print_invalid (ndo );
464+ offset += inft_name_length_field ;
465+ break ;
466+ }
467+ if (inft_name_length_field > 64 ) {
468+ ND_PRINT (" [length %u > 64]" , inft_name_length_field );
469+ nd_print_invalid (ndo );
470+ offset += inft_name_length_field ;
471+ break ;
472+ }
473+ ND_PRINT (", length %u: " , inft_name_length_field );
474+ nd_printjnp (ndo , ifname_subobj -> if_name ,
475+ inft_name_length_field - 1 );
476+ offset += inft_name_length_field ;
477+ }
478+ if (mtu_flag ) {
479+ ND_PRINT ("\n\t MTU: %u" , GET_BE_U_4 (offset ));
480+ offset += 4 ;
481+ }
482+ break ;
483+ }
484+
485+ default :
486+ print_unknown_data (ndo , obj_tptr , "\n\t " , obj_tlen );
487+ break ;
488+ }
489+ return obj_tlen + sizeof (struct icmp_multipart_ext_object_header_t );
490+ }
491+
356492void
357493icmp_print (netdissect_options * ndo , const u_char * bp , u_int plen ,
358494 int fragmented )
@@ -782,139 +918,12 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen,
782918 obj_tptr = (const uint8_t * )ext_dp -> icmp_ext_data ;
783919
784920 while (hlen > sizeof (struct icmp_multipart_ext_object_header_t )) {
785- u_int obj_tlen , obj_class_num , obj_ctype ;
786- const struct icmp_multipart_ext_object_header_t * icmp_multipart_ext_object_header ;
787-
788- icmp_multipart_ext_object_header = (const struct icmp_multipart_ext_object_header_t * )obj_tptr ;
789- obj_tlen = GET_BE_U_2 (icmp_multipart_ext_object_header -> length );
790- obj_class_num = GET_U_1 (icmp_multipart_ext_object_header -> class_num );
791- obj_ctype = GET_U_1 (icmp_multipart_ext_object_header -> ctype );
792- obj_tptr += sizeof (struct icmp_multipart_ext_object_header_t );
793-
794- ND_PRINT ("\n\t %s (%u), Class-Type: %u, length %u" ,
795- tok2str (icmp_multipart_ext_obj_values ,"unknown" ,obj_class_num ),
796- obj_class_num ,
797- obj_ctype ,
798- obj_tlen );
799-
800- hlen -= sizeof (struct icmp_multipart_ext_object_header_t ); /* length field includes tlv header */
801-
802- /* infinite loop protection */
803- if ((obj_class_num == 0 ) ||
804- (obj_tlen < sizeof (struct icmp_multipart_ext_object_header_t ))) {
921+ int obj_tlen = print_icmp_multipart_ext_object (ndo , obj_tptr );
922+ if (obj_tlen < 0 ) {
923+ /* malformed object */
805924 return ;
806925 }
807- obj_tlen -= sizeof (struct icmp_multipart_ext_object_header_t );
808-
809- switch (obj_class_num ) {
810- case MPLS_STACK_ENTRY_OBJECT_CLASS :
811- switch (obj_ctype ) {
812- case 1 :
813- {
814- uint32_t raw_label ;
815-
816- raw_label = GET_BE_U_4 (obj_tptr );
817- ND_PRINT ("\n\t label %u, tc %u" , MPLS_LABEL (raw_label ), MPLS_TC (raw_label ));
818- if (MPLS_STACK (raw_label ))
819- ND_PRINT (", [S]" );
820- ND_PRINT (", ttl %u" , MPLS_TTL (raw_label ));
821- break ;
822- }
823- default :
824- print_unknown_data (ndo , obj_tptr , "\n\t " , obj_tlen );
825- }
826- break ;
827-
828- case INTERFACE_INFORMATION_OBJECT_CLASS :
829- {
830- /*
831- Ctype in a INTERFACE_INFORMATION_OBJECT_CLASS object:
832-
833- Bit 0 1 2 3 4 5 6 7
834- +-------+-------+-------+-------+-------+-------+-------+-------+
835- | Interface Role| Rsvd1 | Rsvd2 |ifIndex| IPAddr| name | MTU |
836- +-------+-------+-------+-------+-------+-------+-------+-------+
837- */
838- const uint8_t * offset ;
839- u_int interface_role , if_index_flag , ipaddr_flag , name_flag , mtu_flag ;
840-
841- interface_role = (obj_ctype & 0xc0 ) >> 6 ;
842- if_index_flag = (obj_ctype & 0x8 ) >> 3 ;
843- ipaddr_flag = (obj_ctype & 0x4 ) >> 2 ;
844- name_flag = (obj_ctype & 0x2 ) >> 1 ;
845- mtu_flag = (obj_ctype & 0x1 );
846-
847- ND_PRINT ("\n\t Interface Role: %s" ,
848- tok2str (icmp_interface_information_role_values ,
849- "an unknown interface role" ,interface_role ));
850-
851- offset = obj_tptr ;
852-
853- if (if_index_flag ) {
854- ND_PRINT ("\n\t Interface Index: %u" , GET_BE_U_4 (offset ));
855- offset += 4 ;
856- }
857- if (ipaddr_flag ) {
858- const struct icmp_interface_information_ipaddr_subobject_t * ipaddr_subobj ;
859-
860- ND_PRINT ("\n\t IP Address sub-object: " );
861- ipaddr_subobj = (const struct icmp_interface_information_ipaddr_subobject_t * ) offset ;
862- switch (GET_BE_U_2 (ipaddr_subobj -> afi )) {
863- case 1 :
864- ND_PRINT ("%s" , GET_IPADDR_STRING (ipaddr_subobj -> ip_addr ));
865- offset += 4 ;
866- break ;
867- case 2 :
868- ND_PRINT ("%s" , GET_IP6ADDR_STRING (ipaddr_subobj -> ip_addr ));
869- offset += 16 ;
870- break ;
871- default :
872- ND_PRINT ("Unknown Address Family Identifier" );
873- return ;
874- }
875- offset += 4 ;
876- }
877- if (name_flag ) {
878- uint8_t inft_name_length_field ;
879- const struct icmp_interface_information_ifname_subobject_t * ifname_subobj ;
880-
881- ifname_subobj = (const struct icmp_interface_information_ifname_subobject_t * ) offset ;
882- inft_name_length_field = GET_U_1 (ifname_subobj -> length );
883- ND_PRINT ("\n\t Interface Name" );
884- if (inft_name_length_field == 0 ) {
885- ND_PRINT (" [length %u]" , inft_name_length_field );
886- nd_print_invalid (ndo );
887- break ;
888- }
889- if (inft_name_length_field % 4 != 0 ) {
890- ND_PRINT (" [length %u != N x 4]" , inft_name_length_field );
891- nd_print_invalid (ndo );
892- offset += inft_name_length_field ;
893- break ;
894- }
895- if (inft_name_length_field > 64 ) {
896- ND_PRINT (" [length %u > 64]" , inft_name_length_field );
897- nd_print_invalid (ndo );
898- offset += inft_name_length_field ;
899- break ;
900- }
901- ND_PRINT (", length %u: " , inft_name_length_field );
902- nd_printjnp (ndo , ifname_subobj -> if_name ,
903- inft_name_length_field - 1 );
904- offset += inft_name_length_field ;
905- }
906- if (mtu_flag ) {
907- ND_PRINT ("\n\t MTU: %u" , GET_BE_U_4 (offset ));
908- offset += 4 ;
909- }
910- break ;
911- }
912-
913- default :
914- print_unknown_data (ndo , obj_tptr , "\n\t " , obj_tlen );
915- break ;
916- }
917- if (hlen < obj_tlen )
926+ if (hlen < (u_int )obj_tlen )
918927 break ;
919928 hlen -= obj_tlen ;
920929 obj_tptr += obj_tlen ;
0 commit comments