2 * ipmroute.c "ip mroute".
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.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
18 #include <sys/ioctl.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
24 #include <linux/netdevice.h>
26 #include <linux/if_arp.h>
27 #include <linux/sockios.h>
34 static void usage(void) __attribute__((noreturn));
36 static void usage(void)
38 fprintf(stderr, "Usage: ip mroute show [ PREFIX ] [ from PREFIX ] [ iif DEVICE ]\n");
40 fprintf(stderr, "Usage: ip mroute [ add | del ] DESTINATION from SOURCE [ iif DEVICE ] [ oif DEVICE ]\n");
45 static char *viftable[32];
53 static void read_viftable(void)
56 FILE *fp = fopen("/proc/net/ip_mr_vif", "r");
61 if (!fgets(buf, sizeof(buf), fp))
64 while (fgets(buf, sizeof(buf), fp)) {
68 if (sscanf(buf, "%d%s", &vifi, dev) < 2)
71 if (vifi<0 || vifi>31)
74 viftable[vifi] = strdup(dev);
79 static void read_mroute_list(FILE *ofp)
82 FILE *fp = fopen("/proc/net/ip_mr_cache", "r");
87 if (!fgets(buf, sizeof(buf), fp))
90 while (fgets(buf, sizeof(buf), fp)) {
91 inet_prefix maddr, msrc;
100 if (sscanf(buf, "%x%x%d%u%u%u %[^\n]",
101 maddr.data, msrc.data, &vifi,
102 &pkts, &b, &w, oiflist) < 6)
105 if (vifi!=-1 && (vifi < 0 || vifi>31))
108 if (filter_dev[0] && (vifi<0 || strcmp(filter_dev, viftable[vifi])))
110 if (filter.mdst.family && inet_addr_match(&maddr, &filter.mdst, filter.mdst.bitlen))
112 if (filter.msrc.family && inet_addr_match(&msrc, &filter.msrc, filter.msrc.bitlen))
115 snprintf(obuf, sizeof(obuf), "(%s, %s)",
116 format_host(AF_INET, 4, &msrc.data[0], sbuf, sizeof(sbuf)),
117 format_host(AF_INET, 4, &maddr.data[0], mbuf, sizeof(mbuf)));
119 fprintf(ofp, "%-32s Iif: ", obuf);
122 fprintf(ofp, "unresolved ");
124 fprintf(ofp, "%-10s ", viftable[vifi]);
131 fprintf(ofp, "Oifs: ");
134 next = strchr(p, ' ');
139 if (sscanf(p, "%d:%d", &ovifi, &ottl)<2) {
145 fprintf(ofp, "%s", viftable[ovifi]);
147 fprintf(ofp, "(ttl %d) ", ovifi);
153 if (show_stats && b) {
154 fprintf(ofp, "%s %u packets, %u bytes", _SL_, pkts, b);
156 fprintf(ofp, ", %u arrived on wrong iif.", w);
164 static int mroute_list(int argc, char **argv)
167 if (strcmp(*argv, "iif") == 0) {
169 strncpy(filter_dev, *argv, sizeof(filter_dev)-1);
170 } else if (matches(*argv, "from") == 0) {
172 get_prefix(&filter.msrc, *argv, AF_INET);
174 if (strcmp(*argv, "to") == 0) {
177 if (matches(*argv, "help") == 0)
179 get_prefix(&filter.mdst, *argv, AF_INET);
185 read_mroute_list(stdout);
189 int do_multiroute(int argc, char **argv)
192 return mroute_list(0, NULL);
194 if (matches(*argv, "add") == 0)
195 return mroute_modify(RTM_NEWADDR, argc-1, argv+1);
196 if (matches(*argv, "delete") == 0)
197 return mroute_modify(RTM_DELADDR, argc-1, argv+1);
198 if (matches(*argv, "get") == 0)
199 return mroute_get(argc-1, argv+1);
201 if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
202 || matches(*argv, "lst") == 0)
203 return mroute_list(argc-1, argv+1);
204 if (matches(*argv, "help") == 0)
206 fprintf(stderr, "Command \"%s\" is unknown, try \"ip mroute help\".\n", *argv);