]>
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 <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");
53 void read_viftable(void)
56 FILE *fp
= fopen("/proc/net/ip_mr_vif", "r");
61 fgets(buf
, sizeof(buf
), fp
);
63 while (fgets(buf
, sizeof(buf
), fp
)) {
67 if (sscanf(buf
, "%d%s", &vifi
, dev
) < 2)
70 if (vifi
<0 || vifi
>31)
73 viftable
[vifi
] = strdup(dev
);
78 void read_mroute_list(FILE *ofp
)
81 FILE *fp
= fopen("/proc/net/ip_mr_cache", "r");
86 fgets(buf
, sizeof(buf
), fp
);
88 while (fgets(buf
, sizeof(buf
), fp
)) {
89 inet_prefix maddr
, msrc
;
98 if (sscanf(buf
, "%x%x%d%u%u%u%s", maddr
.data
, msrc
.data
, &vifi
,
99 &pkts
, &b
, &w
, oiflist
) < 6)
102 if (vifi
!=-1 && (vifi
< 0 || vifi
>31))
105 if (filter_dev
[0] && (vifi
<0 || strcmp(filter_dev
, viftable
[vifi
])))
107 if (filter
.mdst
.family
&& inet_addr_match(&maddr
, &filter
.mdst
, filter
.mdst
.bitlen
))
109 if (filter
.msrc
.family
&& inet_addr_match(&msrc
, &filter
.msrc
, filter
.msrc
.bitlen
))
112 snprintf(obuf
, sizeof(obuf
), "(%s, %s)",
113 format_host(AF_INET
, 4, &msrc
.data
[0], sbuf
, sizeof(sbuf
)),
114 format_host(AF_INET
, 4, &maddr
.data
[0], mbuf
, sizeof(mbuf
)));
116 fprintf(ofp
, "%-32s Iif: ", obuf
);
119 fprintf(ofp
, "unresolved ");
121 fprintf(ofp
, "%-10s ", viftable
[vifi
]);
128 fprintf(ofp
, "Oifs: ");
131 next
= strchr(p
, ' ');
136 if (sscanf(p
, "%d:%d", &ovifi
, &ottl
)<2) {
142 fprintf(ofp
, "%s", viftable
[ovifi
]);
144 fprintf(ofp
, "(ttl %d) ", ovifi
);
150 if (show_stats
&& b
) {
151 fprintf(ofp
, "%s %u packets, %u bytes", _SL_
, pkts
, b
);
153 fprintf(ofp
, ", %u arrived on wrong iif.", w
);
161 static int mroute_list(int argc
, char **argv
)
164 if (strcmp(*argv
, "iif") == 0) {
166 strncpy(filter_dev
, *argv
, sizeof(filter_dev
)-1);
167 } else if (matches(*argv
, "from") == 0) {
169 get_prefix(&filter
.msrc
, *argv
, AF_INET
);
171 if (strcmp(*argv
, "to") == 0) {
174 if (matches(*argv
, "help") == 0)
176 get_prefix(&filter
.mdst
, *argv
, AF_INET
);
182 read_mroute_list(stdout
);
186 int do_multiroute(int argc
, char **argv
)
189 return mroute_list(0, NULL
);
191 if (matches(*argv
, "add") == 0)
192 return mroute_modify(RTM_NEWADDR
, argc
-1, argv
+1);
193 if (matches(*argv
, "delete") == 0)
194 return mroute_modify(RTM_DELADDR
, argc
-1, argv
+1);
195 if (matches(*argv
, "get") == 0)
196 return mroute_get(argc
-1, argv
+1);
198 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
199 || matches(*argv
, "lst") == 0)
200 return mroute_list(argc
-1, argv
+1);
201 if (matches(*argv
, "help") == 0)
203 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip mroute help\".\n", *argv
);