Commit d7bd2db5 authored by Mathias Nyman's avatar Mathias Nyman Committed by Stephen Hemminger

ip: Add color output option

It is hard to quickly find what you are looking for in the output of the
ip command. Color helps.

This patch adds a '-c' flag to highlight these with individual colors:
  - interface name
  - ip address
  - mac address
  - up/down state
Signed-off-by: default avatarMathias Nyman <m.nyman@iki.fi>
Tested-by: default avatarYegor Yefremov <yegorslists@googlemail.com>
parent aeedd8e1
#ifndef __COLOR_H__
#define __COLOR_H__ 1
enum color_attr {
COLOR_IFNAME,
COLOR_MAC,
COLOR_INET,
COLOR_INET6,
COLOR_OPERSTATE_UP,
COLOR_OPERSTATE_DOWN
};
void enable_color(void);
int color_fprintf(FILE *fp, enum color_attr attr, const char *fmt, ...);
#endif
......@@ -23,6 +23,7 @@
#include "utils.h"
#include "ip_common.h"
#include "namespace.h"
#include "color.h"
int preferred_family = AF_UNSPEC;
int human_readable = 0;
......@@ -56,7 +57,7 @@ static void usage(void)
" -4 | -6 | -I | -D | -B | -0 |\n"
" -l[oops] { maximum-addr-flush-attempts } |\n"
" -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n"
" -rc[vbuf] [size] | -n[etns] name | -a[ll] }\n");
" -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}\n");
exit(-1);
}
......@@ -257,6 +258,8 @@ int main(int argc, char **argv)
exit(-1);
}
rcvbuf = size;
} else if (matches(opt, "-color") == 0) {
enable_color();
} else if (matches(opt, "-help") == 0) {
usage();
} else if (matches(opt, "-netns") == 0) {
......
......@@ -34,6 +34,7 @@
#include "utils.h"
#include "ll_map.h"
#include "ip_common.h"
#include "color.h"
enum {
IPADD_LIST,
......@@ -136,8 +137,15 @@ static void print_operstate(FILE *f, __u8 state)
{
if (state >= sizeof(oper_states)/sizeof(oper_states[0]))
fprintf(f, "state %#x ", state);
else
fprintf(f, "state %s ", oper_states[state]);
else {
fprintf(f, "state ");
if (strcmp(oper_states[state], "UP") == 0)
color_fprintf(f, COLOR_OPERSTATE_UP, "%s ", oper_states[state]);
else if (strcmp(oper_states[state], "DOWN") == 0)
color_fprintf(f, COLOR_OPERSTATE_DOWN, "%s ", oper_states[state]);
else
fprintf(f, "%s ", oper_states[state]);
}
}
int get_operstate(const char *name)
......@@ -606,7 +614,8 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (n->nlmsg_type == RTM_DELLINK)
fprintf(fp, "Deleted ");
fprintf(fp, "%d: %s", ifi->ifi_index,
fprintf(fp, "%d: ", ifi->ifi_index);
color_fprintf(fp, COLOR_IFNAME, "%s",
tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");
if (tb[IFLA_LINK]) {
......@@ -666,10 +675,11 @@ int print_linkinfo(const struct sockaddr_nl *who,
fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
if (tb[IFLA_ADDRESS]) {
fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
RTA_PAYLOAD(tb[IFLA_ADDRESS]),
ifi->ifi_type,
b1, sizeof(b1)));
color_fprintf(fp, COLOR_MAC, "%s",
ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
RTA_PAYLOAD(tb[IFLA_ADDRESS]),
ifi->ifi_type,
b1, sizeof(b1)));
}
if (tb[IFLA_BROADCAST]) {
if (ifi->ifi_flags&IFF_POINTOPOINT)
......@@ -849,10 +859,21 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
fprintf(fp, " family %d ", ifa->ifa_family);
if (rta_tb[IFA_LOCAL]) {
fprintf(fp, "%s", format_host(ifa->ifa_family,
RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
RTA_DATA(rta_tb[IFA_LOCAL]),
abuf, sizeof(abuf)));
if (ifa->ifa_family == AF_INET)
color_fprintf(fp, COLOR_INET, "%s", format_host(ifa->ifa_family,
RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
RTA_DATA(rta_tb[IFA_LOCAL]),
abuf, sizeof(abuf)));
else if (ifa->ifa_family == AF_INET6)
color_fprintf(fp, COLOR_INET6, "%s", format_host(ifa->ifa_family,
RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
RTA_DATA(rta_tb[IFA_LOCAL]),
abuf, sizeof(abuf)));
else
fprintf(fp, "%s", format_host(ifa->ifa_family,
RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
RTA_DATA(rta_tb[IFA_LOCAL]),
abuf, sizeof(abuf)));
if (rta_tb[IFA_ADDRESS] == NULL ||
memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]),
......
......@@ -7,7 +7,7 @@ endif
CFLAGS += -fPIC
UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o namespace.o \
names.o
names.o color.o
NLOBJ=libgenl.o ll_map.o libnetlink.o
......
#include <stdio.h>
#include <stdarg.h>
#include "color.h"
enum color {
C_RED,
C_GREEN,
C_YELLOW,
C_BLUE,
C_MAGENTA,
C_CYAN,
C_WHITE,
C_CLEAR
};
static const char * const color_codes[] = {
"\e[31m",
"\e[32m",
"\e[33m",
"\e[34m",
"\e[35m",
"\e[36m",
"\e[37m",
"\e[0m",
NULL,
};
static enum color attr_colors[] = {
C_CYAN,
C_YELLOW,
C_MAGENTA,
C_BLUE,
C_GREEN,
C_RED
};
static int color_is_enabled;
void enable_color(void)
{
color_is_enabled = 1;
}
int color_fprintf(FILE *fp, enum color_attr attr, const char *fmt, ...)
{
int ret = 0;
va_list args;
va_start(args, fmt);
if (!color_is_enabled) {
ret = vfprintf(fp, fmt, args);
goto end;
}
ret += fprintf(fp, "%s", color_codes[attr_colors[attr]]);
ret += vfprintf(fp, fmt, args);
ret += fprintf(fp, "%s", color_codes[C_CLEAR]);
end:
va_end(args);
return ret;
}
......@@ -33,7 +33,8 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
.BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | "
\fB\-o\fR[\fIneline\fR] |
\fB\-n\fR[\fIetns\fR] name |
\fB\-a\fR[\fIll\fR] }
\fB\-a\fR[\fIll\fR] |
\fB\-c\fR[\fIolor\fR] }
.SH OPTIONS
......@@ -165,6 +166,10 @@ to
.BR "\-a" , " \-all"
executes specified command over all objects, it depends if command supports this option.
.TP
.BR "\-c" , " -color"
Use color output.
.SH IP - COMMAND SYNTAX
.SS
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment