]> git.proxmox.com Git - mirror_iproute2.git/blob - ip/ipmroute.c
(Logical change 1.3)
[mirror_iproute2.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 <linux/netdevice.h>
21 #include <linux/if.h>
22 #include <linux/if_arp.h>
23 #include <linux/sockios.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
26 #include <string.h>
27
28 #include "utils.h"
29
30 char filter_dev[16];
31 int filter_family;
32
33 static void usage(void) __attribute__((noreturn));
34
35 static void usage(void)
36 {
37 fprintf(stderr, "Usage: ip mroute show [ PREFIX ] [ from PREFIX ] [ iif DEVICE ]\n");
38 #if 0
39 fprintf(stderr, "Usage: ip mroute [ add | del ] DESTINATION from SOURCE [ iif DEVICE ] [ oif DEVICE ]\n");
40 #endif
41 exit(-1);
42 }
43
44 char *viftable[32];
45
46 struct rtfilter
47 {
48 inet_prefix mdst;
49 inet_prefix msrc;
50 } filter;
51
52 void read_viftable(void)
53 {
54 char buf[256];
55 FILE *fp = fopen("/proc/net/ip_mr_vif", "r");
56
57 if (!fp)
58 return;
59
60 fgets(buf, sizeof(buf), fp);
61
62 while (fgets(buf, sizeof(buf), fp)) {
63 int vifi;
64 char dev[256];
65
66 if (sscanf(buf, "%d%s", &vifi, dev) < 2)
67 continue;
68
69 if (vifi<0 || vifi>31)
70 continue;
71
72 viftable[vifi] = strdup(dev);
73 }
74 fclose(fp);
75 }
76
77 void read_mroute_list(FILE *ofp)
78 {
79 char buf[256];
80 FILE *fp = fopen("/proc/net/ip_mr_cache", "r");
81
82 if (!fp)
83 return;
84
85 fgets(buf, sizeof(buf), fp);
86
87 while (fgets(buf, sizeof(buf), fp)) {
88 inet_prefix maddr, msrc;
89 unsigned pkts, b, w;
90 int vifi;
91 char oiflist[256];
92 char sbuf[256];
93 char mbuf[256];
94 char obuf[256];
95
96 oiflist[0] = 0;
97 if (sscanf(buf, "%x%x%d%u%u%u%s", maddr.data, msrc.data, &vifi,
98 &pkts, &b, &w, oiflist) < 6)
99 continue;
100
101 if (vifi!=-1 && (vifi < 0 || vifi>31))
102 continue;
103
104 if (filter_dev[0] && (vifi<0 || strcmp(filter_dev, viftable[vifi])))
105 continue;
106 if (filter.mdst.family && inet_addr_match(&maddr, &filter.mdst, filter.mdst.bitlen))
107 continue;
108 if (filter.msrc.family && inet_addr_match(&msrc, &filter.msrc, filter.msrc.bitlen))
109 continue;
110
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)));
114
115 fprintf(ofp, "%-32s Iif: ", obuf);
116
117 if (vifi == -1)
118 fprintf(ofp, "unresolved ");
119 else
120 fprintf(ofp, "%-10s ", viftable[vifi]);
121
122 if (oiflist[0]) {
123 char *next = NULL;
124 char *p = oiflist;
125 int ovifi, ottl;
126
127 fprintf(ofp, "Oifs: ");
128
129 while (p) {
130 next = strchr(p, ' ');
131 if (next) {
132 *next = 0;
133 next++;
134 }
135 if (sscanf(p, "%d:%d", &ovifi, &ottl)<2) {
136 p = next;
137 continue;
138 }
139 p = next;
140
141 fprintf(ofp, "%s", viftable[ovifi]);
142 if (ottl>1)
143 fprintf(ofp, "(ttl %d) ", ovifi);
144 else
145 fprintf(ofp, " ");
146 }
147 }
148
149 if (show_stats && b) {
150 fprintf(ofp, "%s %u packets, %u bytes", _SL_, pkts, b);
151 if (w)
152 fprintf(ofp, ", %u arrived on wrong iif.", w);
153 }
154 fprintf(ofp, "\n");
155 }
156 fclose(fp);
157 }
158
159
160 static int mroute_list(int argc, char **argv)
161 {
162 while (argc > 0) {
163 if (strcmp(*argv, "iif") == 0) {
164 NEXT_ARG();
165 strncpy(filter_dev, *argv, sizeof(filter_dev)-1);
166 } else if (matches(*argv, "from") == 0) {
167 NEXT_ARG();
168 get_prefix(&filter.msrc, *argv, AF_INET);
169 } else {
170 if (strcmp(*argv, "to") == 0) {
171 NEXT_ARG();
172 }
173 if (matches(*argv, "help") == 0)
174 usage();
175 get_prefix(&filter.mdst, *argv, AF_INET);
176 }
177 argv++; argc--;
178 }
179
180 read_viftable();
181 read_mroute_list(stdout);
182 return 0;
183 }
184
185 int do_multiroute(int argc, char **argv)
186 {
187 if (argc < 1)
188 return mroute_list(0, NULL);
189 #if 0
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);
196 #endif
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)
201 usage();
202 fprintf(stderr, "Command \"%s\" is unknown, try \"ip mroute help\".\n", *argv);
203 exit(-1);
204 }