Skip to content

Commit 4bea9a6

Browse files
fennerfxlb
authored andcommitted
ICMP: refactor RFC4884 object printing
For a future change, we refactor RFC4884 object printing into its own function. This change just moves and reindents the lines in question.
1 parent 45bcdc0 commit 4bea9a6

File tree

1 file changed

+140
-131
lines changed

1 file changed

+140
-131
lines changed

print-icmp.c

Lines changed: 140 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
356492
void
357493
icmp_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

Comments
 (0)