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