]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Explicit ip4_addr / ip6_addr printf support
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 29 Dec 2015 16:12:47 +0000 (17:12 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 29 Dec 2015 16:12:47 +0000 (17:12 +0100)
conf/confbase.Y
lib/net.c
lib/printf.c
sysdep/linux/netlink.c

index 06698833766bc2dd7c1a328ee05e6ae63d0bbd17..9b4f54e93da72ecf428807ceafee5eb3746417d6 100644 (file)
@@ -178,7 +178,7 @@ pxlen4:
    }
  | ':' IP4 {
      $$ = ip4_masklen($2);
-     if ($$ == 255) cf_error("Invalid netmask %I", $2); /* XXXX */
+     if ($$ == 255) cf_error("Invalid netmask %I4", $2);
    }
  ;
 
index 76ecd460f5f04b17f448ce73ef14bf8a9129b81f..a78111abbe5b4c36249882f7861024475239b342 100644 (file)
--- a/lib/net.c
+++ b/lib/net.c
@@ -31,17 +31,16 @@ net_format(const net_addr *N, char *buf, int buflen)
 {
   net_addr_union *n = (void *) N;
 
-  /* XXXX fix %I vs %R */
   switch (n->n.type)
   {
   case NET_IP4:
-    return bsnprintf(buf, buflen, "%R/%d", n->ip4.prefix, n->ip4.pxlen);
+    return bsnprintf(buf, buflen, "%I4/%d", n->ip4.prefix, n->ip4.pxlen);
   case NET_IP6:
-    return bsnprintf(buf, buflen, "%I/%d", n->ip6.prefix, n->ip6.pxlen);
+    return bsnprintf(buf, buflen, "%I6/%d", n->ip6.prefix, n->ip6.pxlen);
   case NET_VPN4:
-    return bsnprintf(buf, buflen, "%u:%u %R/%d", (u32) (n->vpn4.rd >> 32), (u32) n->vpn4.rd, n->vpn4.prefix, n->vpn4.pxlen);
+    return bsnprintf(buf, buflen, "%u:%u %I4/%d", (u32) (n->vpn4.rd >> 32), (u32) n->vpn4.rd, n->vpn4.prefix, n->vpn4.pxlen);
   case NET_VPN6:
-    return bsnprintf(buf, buflen, "%u:%u %I/%d", (u32) (n->vpn6.rd >> 32), (u32) n->vpn6.rd, n->vpn6.prefix, n->vpn6.pxlen);
+    return bsnprintf(buf, buflen, "%u:%u %I6/%d", (u32) (n->vpn6.rd >> 32), (u32) n->vpn6.rd, n->vpn6.prefix, n->vpn6.pxlen);
   }
 
   return 0;
index 071fc953a82fb2f8204121da3a52068f92167a2c..ce12202ccd9a68490a7b5398362832b95fa8793f 100644 (file)
@@ -118,15 +118,15 @@ static char * number(char * str, long num, int base, int size, int precision,
  * @fmt: format string
  * @args: a list of arguments to be formatted
  *
- * This functions acts like ordinary sprintf() except that it checks
- * available space to avoid buffer overflows and it allows some more
- * format specifiers: |%I| for formatting of IP addresses (any non-zero
- * width is automatically replaced by standard IP address width which
- * depends on whether we use IPv4 or IPv6; |%#I| gives hexadecimal format),
- * |%R| for Router / Network ID (u32 value printed as IPv4 address)
- * and |%m| resp. |%M| for error messages (uses strerror() to translate @errno code to
- * message text). On the other hand, it doesn't support floating
- * point numbers.
+ * This functions acts like ordinary sprintf() except that it checks available
+ * space to avoid buffer overflows and it allows some more format specifiers:
+ * |%I| for formatting of IP addresses (width of 1 is automatically replaced by
+ * standard IP address width which depends on whether we use IPv4 or IPv6; |%I4|
+ * or |%I6| can be used for explicit ip4_addr / ip6_addr arguments, |%N| for
+ * generic network addresses (net_addr *), |%R| for Router / Network ID (u32
+ * value printed as IPv4 address) and |%m| resp. |%M| for error messages (uses
+ * strerror() to translate @errno code to message text). On the other hand, it
+ * doesn't support floating point numbers.
  *
  * Result: number of characters of the output string or -1 if
  * the buffer space was insufficient.
@@ -168,7 +168,7 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
                                case '#': flags |= SPECIAL; goto repeat;
                                case '0': flags |= ZEROPAD; goto repeat;
                                }
-               
+
                /* get field width */
                field_width = -1;
                if (is_digit(*fmt))
@@ -186,7 +186,7 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
                /* get the precision */
                precision = -1;
                if (*fmt == '.') {
-                       ++fmt;  
+                       ++fmt;
                        if (is_digit(*fmt))
                                precision = skip_atoi(&fmt);
                        else if (*fmt == '*') {
@@ -289,22 +289,36 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
                        continue;
 
                /* IP address */
-               case 'I': {
-                       ip_addr a = va_arg(args, ip_addr);
-                       if (flags & SPECIAL)
-                               ip6_ntox(ipa_to_ip6(a), ipbuf);
-                       else {
-                               // XXXX better IPv4 / IPv6 distinction
-                               if (ipa_is_ip4(a))
+               case 'I':
+                       if (fmt[1] == '4') {
+                               /* Explicit IPv4 address */
+                               ip4_addr a = va_arg(args, ip4_addr);
+                               ip4_ntop(a, ipbuf);
+                               i = IP4_MAX_TEXT_LENGTH;
+                       } else if (fmt[1] == '6') {
+                               /* Explicit IPv6 address */
+                               ip6_addr a = va_arg(args, ip6_addr);
+                               ip6_ntop(a, ipbuf);
+                               i = IP6_MAX_TEXT_LENGTH;
+                       } else {
+                               /* Just IP address */
+                               ip_addr a = va_arg(args, ip_addr);
+
+                               if (ipa_is_ip4(a)) {
                                        ip4_ntop(ipa_to_ip4(a), ipbuf);
-                               else
+                                       i = IP4_MAX_TEXT_LENGTH;
+                               } else {
                                        ip6_ntop(ipa_to_ip6(a), ipbuf);
-                               if (field_width == 1)
-                                       field_width = (ipa_is_ip4(a) ? IP4_MAX_TEXT_LENGTH : IP6_MAX_TEXT_LENGTH);
+                                       i = IP6_MAX_TEXT_LENGTH;
+                               }
                        }
+
                        s = ipbuf;
+                       if (field_width == 1)
+                               field_width = i;
+
                        goto str;
-                       }
+
                /* Interface scope after link-local IP address */
                case 'J':
                        iface = va_arg(args, struct iface *);
index be790c299bfd1f81d91e36eb9af23e711f62d63c..530cb24035a175f9344a128c85d8edcb7e13c265 100644 (file)
@@ -691,7 +691,7 @@ nl_parse_addr4(struct ifaddrmsg *i, int scan, int new)
            ifa.brd = ipa_from_ip4(xbrd);
          else if (ifi->flags & IF_TMP_DOWN) /* Complain only during the first scan */
            {
-             log(L_ERR "KIF: Invalid broadcast address %I for %s", xbrd, ifi->name);
+             log(L_ERR "KIF: Invalid broadcast address %I4 for %s", xbrd, ifi->name);
              ifa.brd = ipa_from_ip4(ybrd);
            }
        }