]>
Commit | Line | Data |
---|---|---|
d04bc300 SH |
1 | |
2 | #include <stdio.h> | |
3 | #include <stdlib.h> | |
4 | #include <unistd.h> | |
5 | #include <time.h> | |
6 | #include <sys/socket.h> | |
7 | #include <sys/time.h> | |
8 | #include <netinet/in.h> | |
9 | #include <linux/if.h> | |
10 | #include <linux/if_bridge.h> | |
11 | #include <string.h> | |
12 | ||
13 | #include "utils.h" | |
14 | #include "br_common.h" | |
15 | ||
16 | static const char *port_states[] = { | |
17 | [BR_STATE_DISABLED] = "disabled", | |
18 | [BR_STATE_LISTENING] = "listening", | |
19 | [BR_STATE_LEARNING] = "learning", | |
20 | [BR_STATE_FORWARDING] = "forwarding", | |
21 | [BR_STATE_BLOCKING] = "blocking", | |
22 | }; | |
23 | ||
24 | extern char *if_indextoname (unsigned int __ifindex, char *__ifname); | |
25 | ||
26 | static void print_link_flags(FILE *fp, unsigned flags) | |
27 | { | |
28 | fprintf(fp, "<"); | |
29 | if (flags & IFF_UP && !(flags & IFF_RUNNING)) | |
30 | fprintf(fp, "NO-CARRIER%s", flags ? "," : ""); | |
31 | flags &= ~IFF_RUNNING; | |
32 | #define _PF(f) if (flags&IFF_##f) { \ | |
33 | flags &= ~IFF_##f ; \ | |
34 | fprintf(fp, #f "%s", flags ? "," : ""); } | |
35 | _PF(LOOPBACK); | |
36 | _PF(BROADCAST); | |
37 | _PF(POINTOPOINT); | |
38 | _PF(MULTICAST); | |
39 | _PF(NOARP); | |
40 | _PF(ALLMULTI); | |
41 | _PF(PROMISC); | |
42 | _PF(MASTER); | |
43 | _PF(SLAVE); | |
44 | _PF(DEBUG); | |
45 | _PF(DYNAMIC); | |
46 | _PF(AUTOMEDIA); | |
47 | _PF(PORTSEL); | |
48 | _PF(NOTRAILERS); | |
49 | _PF(UP); | |
50 | _PF(LOWER_UP); | |
51 | _PF(DORMANT); | |
52 | _PF(ECHO); | |
53 | #undef _PF | |
54 | if (flags) | |
55 | fprintf(fp, "%x", flags); | |
56 | fprintf(fp, "> "); | |
57 | } | |
58 | ||
59 | static const char *oper_states[] = { | |
38df7ac9 | 60 | "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN", |
d04bc300 SH |
61 | "TESTING", "DORMANT", "UP" |
62 | }; | |
63 | ||
64 | static void print_operstate(FILE *f, __u8 state) | |
65 | { | |
66 | if (state >= sizeof(oper_states)/sizeof(oper_states[0])) | |
67 | fprintf(f, "state %#x ", state); | |
68 | else | |
69 | fprintf(f, "state %s ", oper_states[state]); | |
70 | } | |
71 | ||
72 | int print_linkinfo(const struct sockaddr_nl *who, | |
73 | struct nlmsghdr *n, void *arg) | |
74 | { | |
75 | FILE *fp = arg; | |
76 | int len = n->nlmsg_len; | |
77 | struct ifinfomsg *ifi = NLMSG_DATA(n); | |
78 | struct rtattr * tb[IFLA_MAX+1]; | |
79 | char b1[IFNAMSIZ]; | |
80 | ||
81 | len -= NLMSG_LENGTH(sizeof(*ifi)); | |
82 | if (len < 0) { | |
83 | fprintf(stderr, "Message too short!\n"); | |
84 | return -1; | |
85 | } | |
86 | ||
87 | if (!(ifi->ifi_family == AF_BRIDGE || ifi->ifi_family == AF_UNSPEC)) | |
88 | return 0; | |
89 | ||
90 | parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); | |
91 | ||
92 | if (tb[IFLA_IFNAME] == NULL) { | |
93 | fprintf(stderr, "BUG: nil ifname\n"); | |
94 | return -1; | |
95 | } | |
96 | ||
97 | if (n->nlmsg_type == RTM_DELLINK) | |
98 | fprintf(fp, "Deleted "); | |
99 | ||
100 | fprintf(fp, "%d: %s ", ifi->ifi_index, | |
1465db1a | 101 | tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>"); |
d04bc300 | 102 | |
38df7ac9 | 103 | if (tb[IFLA_OPERSTATE]) |
1465db1a | 104 | print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE])); |
38df7ac9 | 105 | |
d04bc300 SH |
106 | if (tb[IFLA_LINK]) { |
107 | SPRINT_BUF(b1); | |
1465db1a | 108 | int iflink = rta_getattr_u32(tb[IFLA_LINK]); |
d04bc300 SH |
109 | if (iflink == 0) |
110 | fprintf(fp, "@NONE: "); | |
1465db1a | 111 | else |
38df7ac9 | 112 | fprintf(fp, "@%s: ", |
d04bc300 | 113 | if_indextoname(iflink, b1)); |
1465db1a | 114 | } else |
d04bc300 | 115 | fprintf(fp, ": "); |
d04bc300 SH |
116 | |
117 | print_link_flags(fp, ifi->ifi_flags); | |
118 | ||
119 | if (tb[IFLA_MTU]) | |
1465db1a | 120 | fprintf(fp, "mtu %u ", rta_getattr_u32(tb[IFLA_MTU])); |
d04bc300 | 121 | |
1465db1a | 122 | if (tb[IFLA_MASTER]) |
38df7ac9 | 123 | fprintf(fp, "master %s ", |
1465db1a | 124 | if_indextoname(rta_getattr_u32(tb[IFLA_MASTER]), b1)); |
d04bc300 SH |
125 | |
126 | if (tb[IFLA_PROTINFO]) { | |
1465db1a | 127 | __u8 state = rta_getattr_u8(tb[IFLA_PROTINFO]); |
d04bc300 SH |
128 | if (state <= BR_STATE_BLOCKING) |
129 | fprintf(fp, "state %s", port_states[state]); | |
130 | else | |
131 | fprintf(fp, "state (%d)", state); | |
132 | } | |
133 | ||
134 | ||
135 | fprintf(fp, "\n"); | |
136 | fflush(fp); | |
137 | return 0; | |
138 | } |