]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/blob - ip/ipmroute.c
gred: support TCA_GRED_MAX_P attribute
[lisovros/iproute2_canprio.git] / ip / ipmroute.c
1 /*
2  * ipmroute.c           "ip mroute".
3  *
4  *              This program is free software; you can redistribute it and/or
5  *              modify it under the terms of the GNU General Public License
6  *              as published by the Free Software Foundation; either version
7  *              2 of the License, or (at your option) any later version.
8  *
9  * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10  *
11  */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <syslog.h>
17 #include <fcntl.h>
18 #include <sys/ioctl.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
22 #include <string.h>
23
24 #include <linux/netdevice.h>
25 #include <linux/if.h>
26 #include <linux/if_arp.h>
27 #include <linux/sockios.h>
28
29 #include "utils.h"
30
31 char filter_dev[16];
32 int  filter_family;
33
34 static void usage(void) __attribute__((noreturn));
35
36 static void usage(void)
37 {
38         fprintf(stderr, "Usage: ip mroute show [ PREFIX ] [ from PREFIX ] [ iif DEVICE ]\n");
39 #if 0
40         fprintf(stderr, "Usage: ip mroute [ add | del ] DESTINATION from SOURCE [ iif DEVICE ] [ oif DEVICE ]\n");
41 #endif
42         exit(-1);
43 }
44
45 static char *viftable[32];
46
47 struct rtfilter
48 {
49         inet_prefix mdst;
50         inet_prefix msrc;
51 } filter;
52
53 static void read_viftable(void)
54 {
55         char buf[256];
56         FILE *fp = fopen("/proc/net/ip_mr_vif", "r");
57
58         if (!fp)
59                 return;
60
61         if (!fgets(buf, sizeof(buf), fp)) {
62                 fclose(fp);
63                 return;
64         }
65         while (fgets(buf, sizeof(buf), fp)) {
66                 int vifi;
67                 char dev[256];
68
69                 if (sscanf(buf, "%d%s", &vifi, dev) < 2)
70                         continue;
71
72                 if (vifi<0 || vifi>31)
73                         continue;
74
75                 viftable[vifi] = strdup(dev);
76         }
77         fclose(fp);
78 }
79
80 static void read_mroute_list(FILE *ofp)
81 {
82         char buf[256];
83         FILE *fp = fopen("/proc/net/ip_mr_cache", "r");
84
85         if (!fp)
86                 return;
87
88         if (!fgets(buf, sizeof(buf), fp)) {
89                 fclose(fp);
90                 return;
91         }
92
93         while (fgets(buf, sizeof(buf), fp)) {
94                 inet_prefix maddr, msrc;
95                 unsigned pkts, b, w;
96                 int vifi;
97                 char oiflist[256];
98                 char sbuf[256];
99                 char mbuf[256];
100                 char obuf[256];
101
102                 oiflist[0] = 0;
103                 if (sscanf(buf, "%x%x%d%u%u%u %[^\n]",
104                            maddr.data, msrc.data, &vifi,
105                            &pkts, &b, &w, oiflist) < 6)
106                         continue;
107
108                 if (vifi!=-1 && (vifi < 0 || vifi>31))
109                         continue;
110
111                 if (filter_dev[0] && (vifi<0 || strcmp(filter_dev, viftable[vifi])))
112                         continue;
113                 if (filter.mdst.family && inet_addr_match(&maddr, &filter.mdst, filter.mdst.bitlen))
114                         continue;
115                 if (filter.msrc.family && inet_addr_match(&msrc, &filter.msrc, filter.msrc.bitlen))
116                         continue;
117
118                 snprintf(obuf, sizeof(obuf), "(%s, %s)",
119                          format_host(AF_INET, 4, &msrc.data[0], sbuf, sizeof(sbuf)),
120                          format_host(AF_INET, 4, &maddr.data[0], mbuf, sizeof(mbuf)));
121
122                 fprintf(ofp, "%-32s Iif: ", obuf);
123
124                 if (vifi == -1)
125                         fprintf(ofp, "unresolved ");
126                 else
127                         fprintf(ofp, "%-10s ", viftable[vifi]);
128
129                 if (oiflist[0]) {
130                         char *next = NULL;
131                         char *p = oiflist;
132                         int ovifi, ottl;
133
134                         fprintf(ofp, "Oifs: ");
135
136                         while (p) {
137                                 next = strchr(p, ' ');
138                                 if (next) {
139                                         *next = 0;
140                                         next++;
141                                 }
142                                 if (sscanf(p, "%d:%d", &ovifi, &ottl)<2) {
143                                         p = next;
144                                         continue;
145                                 }
146                                 p = next;
147
148                                 fprintf(ofp, "%s", viftable[ovifi]);
149                                 if (ottl>1)
150                                         fprintf(ofp, "(ttl %d) ", ovifi);
151                                 else
152                                         fprintf(ofp, " ");
153                         }
154                 }
155
156                 if (show_stats && b) {
157                         fprintf(ofp, "%s  %u packets, %u bytes", _SL_, pkts, b);
158                         if (w)
159                                 fprintf(ofp, ", %u arrived on wrong iif.", w);
160                 }
161                 fprintf(ofp, "\n");
162         }
163         fclose(fp);
164 }
165
166
167 static int mroute_list(int argc, char **argv)
168 {
169         while (argc > 0) {
170                 if (strcmp(*argv, "iif") == 0) {
171                         NEXT_ARG();
172                         strncpy(filter_dev, *argv, sizeof(filter_dev)-1);
173                 } else if (matches(*argv, "from") == 0) {
174                         NEXT_ARG();
175                         get_prefix(&filter.msrc, *argv, AF_INET);
176                 } else {
177                         if (strcmp(*argv, "to") == 0) {
178                                 NEXT_ARG();
179                         }
180                         if (matches(*argv, "help") == 0)
181                                 usage();
182                         get_prefix(&filter.mdst, *argv, AF_INET);
183                 }
184                 argv++; argc--;
185         }
186
187         read_viftable();
188         read_mroute_list(stdout);
189         return 0;
190 }
191
192 int do_multiroute(int argc, char **argv)
193 {
194         if (argc < 1)
195                 return mroute_list(0, NULL);
196 #if 0
197         if (matches(*argv, "add") == 0)
198                 return mroute_modify(RTM_NEWADDR, argc-1, argv+1);
199         if (matches(*argv, "delete") == 0)
200                 return mroute_modify(RTM_DELADDR, argc-1, argv+1);
201         if (matches(*argv, "get") == 0)
202                 return mroute_get(argc-1, argv+1);
203 #endif
204         if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
205             || matches(*argv, "lst") == 0)
206                 return mroute_list(argc-1, argv+1);
207         if (matches(*argv, "help") == 0)
208                 usage();
209         fprintf(stderr, "Command \"%s\" is unknown, try \"ip mroute help\".\n", *argv);
210         exit(-1);
211 }