]> git.proxmox.com Git - mirror_iproute2.git/blame - bridge/link.c
ss: Get udp sockets info via sock-diag
[mirror_iproute2.git] / bridge / link.c
CommitLineData
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
16static 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
24extern char *if_indextoname (unsigned int __ifindex, char *__ifname);
25
26static 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
59static const char *oper_states[] = {
60 "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
61 "TESTING", "DORMANT", "UP"
62};
63
64static 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
72int 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,
101 tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");
102
103 if (tb[IFLA_OPERSTATE])
104 print_operstate(fp, *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE]));
105
106 if (tb[IFLA_LINK]) {
107 SPRINT_BUF(b1);
108 int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
109
110 if (iflink == 0)
111 fprintf(fp, "@NONE: ");
112 else {
113 fprintf(fp, "@%s: ",
114 if_indextoname(iflink, b1));
115 }
116 } else {
117 fprintf(fp, ": ");
118 }
119
120 print_link_flags(fp, ifi->ifi_flags);
121
122 if (tb[IFLA_MTU])
123 fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
124
125 if (tb[IFLA_MASTER]) {
126 fprintf(fp, "master %s ",
127 if_indextoname(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
128 }
129
130 if (tb[IFLA_PROTINFO]) {
131 uint8_t state = *(uint8_t *)RTA_DATA(tb[IFLA_PROTINFO]);
132 if (state <= BR_STATE_BLOCKING)
133 fprintf(fp, "state %s", port_states[state]);
134 else
135 fprintf(fp, "state (%d)", state);
136 }
137
138
139 fprintf(fp, "\n");
140 fflush(fp);
141 return 0;
142}