@@ -353,6 +353,142 @@ icmp_tstamp_print(u_int tstamp)
353
353
return buf ;
354
354
}
355
355
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
+
356
492
void
357
493
icmp_print (netdissect_options * ndo , const u_char * bp , u_int plen ,
358
494
int fragmented )
@@ -782,139 +918,12 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen,
782
918
obj_tptr = (const uint8_t * )ext_dp -> icmp_ext_data ;
783
919
784
920
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 */
805
924
return ;
806
925
}
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 )
918
927
break ;
919
928
hlen -= obj_tlen ;
920
929
obj_tptr += obj_tlen ;
0 commit comments