printk: add %I4, %I6, %i4, %i6 format specifiers
Subsystems (4)
PATCH 1/4 printk: add %I4, %I6, %i4, %i6 format specifiers
For use in printing IPv4, or IPv6 addresses in the usual way:
%i4 and %I4 are currently equivalent and print the address in dot-separated decimal x.x.x.x
%I6 prints 16-bit network order hex with colon separators:
xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
%i6 omits the colons.
--- lib/vsprintf.c | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-)
lib/vsprintf.c +31 -0
@@ -616,6 +616,23 @@ static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width,return string (buf, end, ip6_addr, field_width, precision, flags & ~SPECIAL ); } +static char *ip4_addr_string (char *buf,char *end,u8 *addr,int field_width, +int precision,int flags) +{ +char ip4_addr[4 *4 ];/* (4 * 3 decimal digits), 3 dots and trailing zero */ +char *p = ip4_addr; +int i; + +for (i =0 ; i <4 ; i++) { + p =put_dec_trunc (p, addr[i]); +if (i !=3 ) + *p++ ='.' ; + } + *p ='\0' ; + +return string (buf, end, ip4_addr, field_width, precision, flags & ~SPECIAL ); +} +/* * Show a '%p' thing. A kernel extension is that the '%p' is followed * by an extra set of alphanumeric characters that are extended format
@@ -629,6 +646,10 @@ static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width,* addresses (not the name nor the flags) * - 'M' For a 6-byte MAC address, it prints the address in the * usual colon-separated hex notation +* - 'I' [46] for IPv4/IPv6 addresses printed in the usual way (dot-separated +* decimal for v4 and colon separated network-order 16 bit hex for v6) +* - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is +currently the same * - '6' For a IPv6 address prints the address in network-ordered 16 bit hex * with colon separators *
@@ -650,6 +671,16 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int fieldreturn mac_address_string (buf, end, ptr, field_width, precision, flags);case '6' :return ip6_addr_string (buf, end, ptr, field_width, precision, flags); +case 'i' : + flags |=SPECIAL ; +/* Fallthrough */ +case 'I' : +if (fmt[1 ] =='6' ) +return ip6_addr_string (buf, end, ptr, field_width, precision, flags); +if (fmt[1 ] =='4' ) +return ip4_addr_string (buf, end, ptr, field_width, precision, flags); + flags &= ~SPECIAL ; +break ; } flags |=SMALL ;if (field_width ==-1 ) {
Signature · 1 line
1.6.0.3.756.gb776d
From: Harvey Harrison <[email protected]>
Date: Wed, 29 Oct 2008 11:35:40 -0700
Quoted 11 lines
For use in printing IPv4, or IPv6 addresses in the usual way:
%i4 and %I4 are currently equivalent and print the address in dot-separated decimal x.x.x.x
%I6 prints 16-bit network order hex with colon separators:
xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx%i6 omits the colons.
Signed-off-by Harvey Harrison <[email protected]>
Applied.
lib/vsprintf.c
Quoted 10 lines · Harvey Harrison
For use in printing IPv4, or IPv6 addresses in the usual way:
Signed-off-by Harvey Harrison <[email protected]>--- lib/vsprintf.c | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-)lib/vsprintf.c +0
-0
[]
Quoted 7 lines
lib/vsprintf.c +3
-0@@ -650,6 +671,16 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int fieldreturn mac_address_string (buf, end, ptr, field_width, precision, flags);case '6' :return ip6_addr_string (buf, end, ptr, field_width, precision, flags); +case 'i' : + flags |=SPECIAL ; +/* Fallthrough */
lib/vsprintf.c static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field · line 686
Quoted 10 lines
lib/vsprintf.c +7
-0+case 'I' : +if (fmt[1 ] =='6' ) +return ip6_addr_string (buf, end, ptr, field_width, precision, flags); +if (fmt[1 ] =='4' ) +return ip4_addr_string (buf, end, ptr, field_width, precision, flags); + flags &= ~SPECIAL ; +break ; } flags |=SMALL ;if (field_width ==-1 ) {
Hi Harvey.
I was thinking about extending %p<foo> to support
struct task_struct * and noticed this code isn't
really correct.
SPECIAL should be cleared from flags only when *fmt is 'i' not 'I' and SPECIAL wasn't previously set.
cheers, Joe
Quoted 18 lines · Joe Perches
Quoted 4 lines · Harvey Harrison
lib/vsprintf.c +3
-0return ip6_addr_string (buf, end, ptr, field_width, precision, flags); +case 'i' : + flags |=SPECIAL ; +/* Fallthrough */ lib/vsprintf.c static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field · line 686
Quoted 10 lines
lib/vsprintf.c +7
-0+case 'I' : +if (fmt[1 ] =='6' ) +return ip6_addr_string (buf, end, ptr, field_width, precision, flags); +if (fmt[1 ] =='4' ) +return ip4_addr_string (buf, end, ptr, field_width, precision, flags); + flags &= ~SPECIAL ; +break ; } flags |=SMALL ;if (field_width ==-1 ) {Hi Harvey.
Quoted 7 lines
I was thinking about extending %p<foo> to support
structtask_struct* and noticed this code isn't
really correct.SPECIAL should be cleared from flags only when *fmt is 'i' not 'I' and SPECIAL wasn't previously set.
SPECIAL is set when # is used with the p modifier...which warns as we've already seen. So the only way to set special in the %p case is to use i. Instead of having an if() I just unconditionally clear it (perhaps unnecessarily). Mind you, we only get here if you pass in %p[iI][not 4 or 6]
Cheers,
Harvey