diff options
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r-- | lib/vsprintf.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index a013bbc23717..3b777025d876 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 | ||
584 | static 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 | |||
601 | static 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 | |||
619 | static 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) { |