@@ -360,7 +360,7 @@ Interface IP Address Sub-Object
360
360
struct icmp_interface_information_ipaddr_subobject_t {
361
361
nd_uint16_t afi ;
362
362
nd_uint16_t reserved ;
363
- nd_byte ip_addr [1 ];
363
+ nd_byte ip_addr [];
364
364
};
365
365
366
366
/*
@@ -388,7 +388,7 @@ struct icmp_interface_identification_ipaddr_subobject_t {
388
388
nd_uint16_t afi ;
389
389
nd_uint8_t addrlen ;
390
390
nd_uint8_t reserved ;
391
- nd_byte ip_addr [1 ];
391
+ nd_byte ip_addr [];
392
392
};
393
393
394
394
/* prototypes */
@@ -410,30 +410,45 @@ icmp_tstamp_print(u_int tstamp)
410
410
return buf ;
411
411
}
412
412
413
+ #define CHECK_TLEN (len ) \
414
+ ND_TCHECK_LEN(obj_tptr, len); \
415
+ if (obj_tlen < (len)) { \
416
+ return obj_len; \
417
+ }
418
+
419
+ #define UPDATE_TLEN (len ) \
420
+ obj_tlen -= (len)
421
+
422
+ #define UPDATE_TPTR_AND_TLEN (len ) \
423
+ obj_tptr += (len); \
424
+ obj_tlen -= (len)
425
+
413
426
static int
414
- print_icmp_multipart_ext_object (netdissect_options * ndo , const uint8_t * obj_tptr )
427
+ print_icmp_multipart_ext_object (netdissect_options * ndo , const uint8_t * obj_ptr )
415
428
{
416
- u_int obj_tlen , obj_class_num , obj_ctype ;
429
+ u_int obj_len , obj_class_num , obj_ctype ;
417
430
const struct icmp_multipart_ext_object_header_t * icmp_multipart_ext_object_header ;
431
+ const uint8_t * obj_tptr ;
432
+ u_int obj_tlen ;
418
433
419
- icmp_multipart_ext_object_header = (const struct icmp_multipart_ext_object_header_t * )obj_tptr ;
420
- obj_tlen = GET_BE_U_2 (icmp_multipart_ext_object_header -> length );
434
+ icmp_multipart_ext_object_header = (const struct icmp_multipart_ext_object_header_t * )obj_ptr ;
435
+ obj_len = GET_BE_U_2 (icmp_multipart_ext_object_header -> length );
421
436
obj_class_num = GET_U_1 (icmp_multipart_ext_object_header -> class_num );
422
437
obj_ctype = GET_U_1 (icmp_multipart_ext_object_header -> ctype );
423
- obj_tptr += sizeof (struct icmp_multipart_ext_object_header_t );
424
438
425
439
ND_PRINT ("\n\t %s (%u), Class-Type: %u, length %u" ,
426
440
tok2str (icmp_multipart_ext_obj_values ,"unknown" ,obj_class_num ),
427
441
obj_class_num ,
428
442
obj_ctype ,
429
- obj_tlen );
443
+ obj_len );
430
444
431
445
/* infinite loop protection */
432
- if ((obj_class_num == 0 ) ||
433
- (obj_tlen < sizeof (struct icmp_multipart_ext_object_header_t ))) {
446
+ if ((obj_class_num == 0 ) || /* XXX - why is this necessary? */
447
+ (obj_len < sizeof (struct icmp_multipart_ext_object_header_t ))) {
434
448
return -1 ;
435
449
}
436
- obj_tlen -= sizeof (struct icmp_multipart_ext_object_header_t );
450
+ obj_tptr = obj_ptr + sizeof (struct icmp_multipart_ext_object_header_t );
451
+ obj_tlen = obj_len - sizeof (struct icmp_multipart_ext_object_header_t );
437
452
438
453
switch (obj_class_num ) {
439
454
case MPLS_STACK_ENTRY_OBJECT_CLASS :
@@ -442,6 +457,7 @@ print_icmp_multipart_ext_object(netdissect_options *ndo, const uint8_t *obj_tptr
442
457
{
443
458
uint32_t raw_label ;
444
459
460
+ CHECK_TLEN (4 );
445
461
raw_label = GET_BE_U_4 (obj_tptr );
446
462
ND_PRINT ("\n\t label %u, tc %u" , MPLS_LABEL (raw_label ), MPLS_TC (raw_label ));
447
463
if (MPLS_STACK (raw_label ))
@@ -464,7 +480,6 @@ print_icmp_multipart_ext_object(netdissect_options *ndo, const uint8_t *obj_tptr
464
480
| Interface Role| Rsvd1 | Rsvd2 |ifIndex| IPAddr| name | MTU |
465
481
+-------+-------+-------+-------+-------+-------+-------+-------+
466
482
*/
467
- const uint8_t * offset ;
468
483
u_int interface_role , if_index_flag , ipaddr_flag , name_flag , mtu_flag ;
469
484
470
485
interface_role = (obj_ctype & 0xc0 ) >> 6 ;
@@ -477,92 +492,119 @@ print_icmp_multipart_ext_object(netdissect_options *ndo, const uint8_t *obj_tptr
477
492
tok2str (icmp_interface_information_role_values ,
478
493
"an unknown interface role" ,interface_role ));
479
494
480
- offset = obj_tptr ;
481
-
482
495
if (if_index_flag ) {
483
- ND_PRINT ("\n\t Interface Index: %u" , GET_BE_U_4 (offset ));
484
- offset += 4 ;
496
+ CHECK_TLEN (4 );
497
+ ND_PRINT ("\n\t Interface Index: %u" , GET_BE_U_4 (obj_tptr ));
498
+ UPDATE_TPTR_AND_TLEN (4 );
485
499
}
486
500
if (ipaddr_flag ) {
501
+ uint16_t afi ;
487
502
const struct icmp_interface_information_ipaddr_subobject_t * ipaddr_subobj ;
488
503
489
504
ND_PRINT ("\n\t IP Address sub-object: " );
490
- ipaddr_subobj = (const struct icmp_interface_information_ipaddr_subobject_t * ) offset ;
491
- switch (GET_BE_U_2 (ipaddr_subobj -> afi )) {
505
+ ipaddr_subobj = (const struct icmp_interface_information_ipaddr_subobject_t * ) obj_tptr ;
506
+
507
+ CHECK_TLEN (sizeof * ipaddr_subobj );
508
+
509
+ /* AFI */
510
+ afi = GET_BE_U_2 (ipaddr_subobj -> afi );
511
+
512
+ /* Reserved space */
513
+ ND_TCHECK_1 (ipaddr_subobj -> reserved );
514
+
515
+ UPDATE_TPTR_AND_TLEN (sizeof * ipaddr_subobj );
516
+
517
+ switch (afi ) {
492
518
case 1 :
519
+ CHECK_TLEN (4 );
493
520
ND_PRINT ("%s" , GET_IPADDR_STRING (ipaddr_subobj -> ip_addr ));
494
- offset += 4 ;
521
+ UPDATE_TPTR_AND_TLEN ( 4 ) ;
495
522
break ;
496
523
case 2 :
524
+ CHECK_TLEN (16 );
497
525
ND_PRINT ("%s" , GET_IP6ADDR_STRING (ipaddr_subobj -> ip_addr ));
498
- offset += 16 ;
526
+ UPDATE_TPTR_AND_TLEN ( 16 ) ;
499
527
break ;
500
528
default :
501
529
ND_PRINT ("Unknown Address Family Identifier" );
502
530
return -1 ;
503
531
}
504
- offset += 4 ;
505
532
}
506
533
if (name_flag ) {
507
534
uint8_t inft_name_length_field ;
508
535
const struct icmp_interface_information_ifname_subobject_t * ifname_subobj ;
509
536
510
- ifname_subobj = (const struct icmp_interface_information_ifname_subobject_t * ) offset ;
537
+ ifname_subobj = (const struct icmp_interface_information_ifname_subobject_t * ) obj_tptr ;
538
+ CHECK_TLEN (1 );
511
539
inft_name_length_field = GET_U_1 (ifname_subobj -> length );
540
+
512
541
ND_PRINT ("\n\t Interface Name" );
513
- if (inft_name_length_field == 0 ) {
542
+ if (inft_name_length_field < 1 ) {
514
543
ND_PRINT (" [length %u]" , inft_name_length_field );
515
544
nd_print_invalid (ndo );
516
545
break ;
517
546
}
547
+ CHECK_TLEN (inft_name_length_field );
518
548
if (inft_name_length_field % 4 != 0 ) {
519
549
ND_PRINT (" [length %u != N x 4]" , inft_name_length_field );
520
550
nd_print_invalid (ndo );
521
- offset += inft_name_length_field ;
551
+ UPDATE_TPTR_AND_TLEN ( inft_name_length_field ) ;
522
552
break ;
523
553
}
524
554
if (inft_name_length_field > 64 ) {
525
555
ND_PRINT (" [length %u > 64]" , inft_name_length_field );
526
556
nd_print_invalid (ndo );
527
- offset += inft_name_length_field ;
557
+ UPDATE_TPTR_AND_TLEN ( inft_name_length_field ) ;
528
558
break ;
529
559
}
530
560
ND_PRINT (", length %u: " , inft_name_length_field );
531
561
nd_printjnp (ndo , ifname_subobj -> if_name ,
532
562
inft_name_length_field - 1 );
533
- offset += inft_name_length_field ;
563
+ UPDATE_TPTR_AND_TLEN ( inft_name_length_field ) ;
534
564
}
535
565
if (mtu_flag ) {
536
- ND_PRINT ("\n\t MTU: %u" , GET_BE_U_4 (offset ));
537
- offset += 4 ;
566
+ CHECK_TLEN (4 );
567
+ ND_PRINT ("\n\t MTU: %u" , GET_BE_U_4 (obj_tptr ));
568
+ UPDATE_TPTR_AND_TLEN (4 );
538
569
}
539
570
break ;
540
571
}
541
572
542
573
case INTERFACE_IDENTIFICATION_OBJECT_CLASS :
543
574
switch (obj_ctype ) {
544
575
case 1 :
545
- ND_PRINT ("\n\t Interface Name, length %d : " , obj_tlen );
576
+ ND_PRINT ("\n\t Interface Name, length %u : " , obj_tlen );
546
577
nd_printjnp (ndo , obj_tptr , obj_tlen );
547
578
break ;
548
579
case 2 :
580
+ CHECK_TLEN (4 );
549
581
ND_PRINT ("\n\t Interface Index: %u" , GET_BE_U_4 (obj_tptr ));
550
582
break ;
551
583
case 3 :
552
584
{
553
585
const struct icmp_interface_identification_ipaddr_subobject_t * id_ipaddr_subobj ;
586
+ uint16_t afi ;
587
+ uint8_t addrlen ;
588
+
554
589
ND_PRINT ("\n\t IP Address sub-object: " );
555
590
id_ipaddr_subobj = (const struct icmp_interface_identification_ipaddr_subobject_t * ) obj_tptr ;
556
- switch (GET_BE_U_2 (id_ipaddr_subobj -> afi )) {
591
+ CHECK_TLEN (sizeof * id_ipaddr_subobj );
592
+ afi = GET_BE_U_2 (id_ipaddr_subobj -> afi );
593
+ addrlen = GET_U_1 (id_ipaddr_subobj -> addrlen );
594
+ ND_TCHECK_1 (id_ipaddr_subobj -> reserved );
595
+ UPDATE_TLEN (sizeof * id_ipaddr_subobj );
596
+
597
+ CHECK_TLEN (addrlen );
598
+ switch (afi ) {
557
599
case 1 :
558
- if (GET_U_1 ( id_ipaddr_subobj -> addrlen ) != 4 ) {
559
- ND_PRINT ("[length %d != 4] " , GET_U_1 ( id_ipaddr_subobj -> addrlen ) );
600
+ if (addrlen != 4 ) {
601
+ ND_PRINT ("[length %d != 4] " , addrlen );
560
602
}
561
603
ND_PRINT ("%s" , GET_IPADDR_STRING (id_ipaddr_subobj -> ip_addr ));
562
604
break ;
563
605
case 2 :
564
- if (GET_U_1 ( id_ipaddr_subobj -> addrlen ) != 16 ) {
565
- ND_PRINT ("[length %d != 16] " , GET_U_1 ( id_ipaddr_subobj -> addrlen ) );
606
+ if (addrlen != 16 ) {
607
+ ND_PRINT ("[length %d != 16] " , addrlen );
566
608
}
567
609
ND_PRINT ("%s" , GET_IP6ADDR_STRING (id_ipaddr_subobj -> ip_addr ));
568
610
break ;
@@ -582,7 +624,7 @@ print_icmp_multipart_ext_object(netdissect_options *ndo, const uint8_t *obj_tptr
582
624
print_unknown_data (ndo , obj_tptr , "\n\t " , obj_tlen );
583
625
break ;
584
626
}
585
- return obj_tlen + sizeof ( struct icmp_multipart_ext_object_header_t ) ;
627
+ return obj_len ;
586
628
}
587
629
588
630
void
0 commit comments