]>
git.proxmox.com Git - mirror_iproute2.git/blob - ip/ipmroute.c
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 <linux/netdevice.h>
22 #include <linux/if_arp.h>
23 #include <linux/sockios.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
33 static void usage(void) __attribute__((noreturn
));
35 static void usage(void)
37 fprintf(stderr
, "Usage: ip mroute show [ PREFIX ] [ from PREFIX ] [ iif DEVICE ]\n");
39 fprintf(stderr
, "Usage: ip mroute [ add | del ] DESTINATION from SOURCE [ iif DEVICE ] [ oif DEVICE ]\n");
52 void read_viftable(void)
55 FILE *fp
= fopen("/proc/net/ip_mr_vif", "r");
60 fgets(buf
, sizeof(buf
), fp
);
62 while (fgets(buf
, sizeof(buf
), fp
)) {
66 if (sscanf(buf
, "%d%s", &vifi
, dev
) < 2)
69 if (vifi
<0 || vifi
>31)
72 viftable
[vifi
] = strdup(dev
);
77 void read_mroute_list(FILE *ofp
)
80 FILE *fp
= fopen("/proc/net/ip_mr_cache", "r");
85 fgets(buf
, sizeof(buf
), fp
);
87 while (fgets(buf
, sizeof(buf
), fp
)) {
88 inet_prefix maddr
, msrc
;
97 if (sscanf(buf
, "%x%x%d%u%u%u%s", maddr
.data
, msrc
.data
, &vifi
,
98 &pkts
, &b
, &w
, oiflist
) < 6)
101 if (vifi
!=-1 && (vifi
< 0 || vifi
>31))
104 if (filter_dev
[0] && (vifi
<0 || strcmp(filter_dev
, viftable
[vifi
])))
106 if (filter
.mdst
.family
&& inet_addr_match(&maddr
, &filter
.mdst
, filter
.mdst
.bitlen
))
108 if (filter
.msrc
.family
&& inet_addr_match(&msrc
, &filter
.msrc
, filter
.msrc
.bitlen
))
111 snprintf(obuf
, sizeof(obuf
), "(%s, %s)",
112 format_host(AF_INET
, 4, &msrc
.data
[0], sbuf
, sizeof(sbuf
)),
113 format_host(AF_INET
, 4, &maddr
.data
[0], mbuf
, sizeof(mbuf
)));
115 fprintf(ofp
, "%-32s Iif: ", obuf
);
118 fprintf(ofp
, "unresolved ");
120 fprintf(ofp
, "%-10s ", viftable
[vifi
]);
127 fprintf(ofp
, "Oifs: ");
130 next
= strchr(p
, ' ');
135 if (sscanf(p
, "%d:%d", &ovifi
, &ottl
)<2) {
141 fprintf(ofp
, "%s", viftable
[ovifi
]);
143 fprintf(ofp
, "(ttl %d) ", ovifi
);
149 if (show_stats
&& b
) {
150 fprintf(ofp
, "%s %u packets, %u bytes", _SL_
, pkts
, b
);
152 fprintf(ofp
, ", %u arrived on wrong iif.", w
);
160 static int mroute_list(int argc
, char **argv
)
163 if (strcmp(*argv
, "iif") == 0) {
165 strncpy(filter_dev
, *argv
, sizeof(filter_dev
)-1);
166 } else if (matches(*argv
, "from") == 0) {
168 get_prefix(&filter
.msrc
, *argv
, AF_INET
);
170 if (strcmp(*argv
, "to") == 0) {
173 if (matches(*argv
, "help") == 0)
175 get_prefix(&filter
.mdst
, *argv
, AF_INET
);
181 read_mroute_list(stdout
);
185 int do_multiroute(int argc
, char **argv
)
188 return mroute_list(0, NULL
);
190 if (matches(*argv
, "add") == 0)
191 return mroute_modify(RTM_NEWADDR
, argc
-1, argv
+1);
192 if (matches(*argv
, "delete") == 0)
193 return mroute_modify(RTM_DELADDR
, argc
-1, argv
+1);
194 if (matches(*argv
, "get") == 0)
195 return mroute_get(argc
-1, argv
+1);
197 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
198 || matches(*argv
, "lst") == 0)
199 return mroute_list(argc
-1, argv
+1);
200 if (matches(*argv
, "help") == 0)
202 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip mroute help\".\n", *argv
);