aboutsummaryrefslogtreecommitdiffstats
path: root/lib/vsprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r--lib/vsprintf.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index a013bbc2371..3b777025d87 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -581,6 +581,62 @@ static char *resource_string(char *buf, char *end, struct resource *res, int fie
581 return string(buf, end, sym, field_width, precision, flags); 581 return string(buf, end, sym, field_width, precision, flags);
582} 582}
583 583
584static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width,
585 int precision, int flags)
586{
587 char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */
588 char *p = mac_addr;
589 int i;
590
591 for (i = 0; i < 6; i++) {
592 p = pack_hex_byte(p, addr[i]);
593 if (!(flags & SPECIAL) && i != 5)
594 *p++ = ':';
595 }
596 *p = '\0';
597
598 return string(buf, end, mac_addr, field_width, precision, flags & ~SPECIAL);
599}
600
601static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width,
602 int precision, int flags)
603{
604 char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */
605 char *p = ip6_addr;
606 int i;
607
608 for (i = 0; i < 8; i++) {
609 p = pack_hex_byte(p, addr[2 * i]);
610 p = pack_hex_byte(p, addr[2 * i + 1]);
611 if (!(flags & SPECIAL) && i != 7)
612 *p++ = ':';
613 }
614 *p = '\0';
615
616 return string(buf, end, ip6_addr, field_width, precision, flags & ~SPECIAL);
617}
618
619static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width,
620 int precision, int flags)
621{
622 char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */
623 char temp[3]; /* hold each IP quad in reverse order */
624 char *p = ip4_addr;
625 int i, digits;
626
627 for (i = 0; i < 4; i++) {
628 digits = put_dec_trunc(temp, addr[i]) - temp;
629 /* reverse the digits in the quad */
630 while (digits--)
631 *p++ = temp[digits];
632 if (i != 3)
633 *p++ = '.';
634 }
635 *p = '\0';
636
637 return string(buf, end, ip4_addr, field_width, precision, flags & ~SPECIAL);
638}
639
584/* 640/*
585 * Show a '%p' thing. A kernel extension is that the '%p' is followed 641 * Show a '%p' thing. A kernel extension is that the '%p' is followed
586 * by an extra set of alphanumeric characters that are extended format 642 * by an extra set of alphanumeric characters that are extended format
@@ -592,6 +648,12 @@ static char *resource_string(char *buf, char *end, struct resource *res, int fie
592 * - 'S' For symbolic direct pointers 648 * - 'S' For symbolic direct pointers
593 * - 'R' For a struct resource pointer, it prints the range of 649 * - 'R' For a struct resource pointer, it prints the range of
594 * addresses (not the name nor the flags) 650 * addresses (not the name nor the flags)
651 * - 'M' For a 6-byte MAC address, it prints the address in the
652 * usual colon-separated hex notation
653 * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way (dot-separated
654 * decimal for v4 and colon separated network-order 16 bit hex for v6)
655 * - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is
656 * currently the same
595 * 657 *
596 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 658 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
597 * function pointers are really function descriptors, which contain a 659 * function pointers are really function descriptors, which contain a
@@ -607,6 +669,21 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
607 return symbol_string(buf, end, ptr, field_width, precision, flags); 669 return symbol_string(buf, end, ptr, field_width, precision, flags);
608 case 'R': 670 case 'R':
609 return resource_string(buf, end, ptr, field_width, precision, flags); 671 return resource_string(buf, end, ptr, field_width, precision, flags);
672 case 'm':
673 flags |= SPECIAL;
674 /* Fallthrough */
675 case 'M':
676 return mac_address_string(buf, end, ptr, field_width, precision, flags);
677 case 'i':
678 flags |= SPECIAL;
679 /* Fallthrough */
680 case 'I':
681 if (fmt[1] == '6')
682 return ip6_addr_string(buf, end, ptr, field_width, precision, flags);
683 if (fmt[1] == '4')
684 return ip4_addr_string(buf, end, ptr, field_width, precision, flags);
685 flags &= ~SPECIAL;
686 break;
610 } 687 }
611 flags |= SMALL; 688 flags |= SMALL;
612 if (field_width == -1) { 689 if (field_width == -1) {