1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/*
2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * ipmroute.c		"ip mroute".
3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		This program is free software; you can redistribute it and/or
5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		modify it under the terms of the GNU General Public License
6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		as published by the Free Software Foundation; either version
7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		2 of the License, or (at your option) any later version.
8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
9aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
11aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */
12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h>
14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h>
15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h>
16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h>
17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h>
18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/ioctl.h>
19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h>
2003156410981dcf7330a33d573154ec4a9302f741osdl.org!shemminger#include <netinet/in.h>
2103156410981dcf7330a33d573154ec4a9302f741osdl.org!shemminger#include <arpa/inet.h>
2203156410981dcf7330a33d573154ec4a9302f741osdl.org!shemminger#include <string.h>
2303156410981dcf7330a33d573154ec4a9302f741osdl.org!shemminger
24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/netdevice.h>
25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if.h>
26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if_arp.h>
27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/sockios.h>
28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h"
30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerchar filter_dev[16];
32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint  filter_family;
33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) __attribute__((noreturn));
35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void)
37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Usage: ip mroute show [ PREFIX ] [ from PREFIX ] [ iif DEVICE ]\n");
39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#if 0
40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Usage: ip mroute [ add | del ] DESTINATION from SOURCE [ iif DEVICE ] [ oif DEVICE ]\n");
41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif
42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
4584616f8317554be7542b2e89b69f4129995cb03bshemmingerstatic char *viftable[32];
46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstruct rtfilter
48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	inet_prefix mdst;
50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	inet_prefix msrc;
51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} filter;
52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
5384616f8317554be7542b2e89b69f4129995cb03bshemmingerstatic void read_viftable(void)
54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char buf[256];
56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *fp = fopen("/proc/net/ip_mr_vif", "r");
57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!fp)
59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return;
60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
6167ef60a29333784d09245762e8270727cc758945Thomas Jarosch	if (!fgets(buf, sizeof(buf), fp)) {
6267ef60a29333784d09245762e8270727cc758945Thomas Jarosch		fclose(fp);
6338c867d2a82d6f2b60450550fbaaadc5d9c77579Stephen Hemminger		return;
6467ef60a29333784d09245762e8270727cc758945Thomas Jarosch	}
65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (fgets(buf, sizeof(buf), fp)) {
66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		int vifi;
67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		char dev[256];
68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (sscanf(buf, "%d%s", &vifi, dev) < 2)
70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
71ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (vifi<0 || vifi>31)
73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		viftable[vifi] = strdup(dev);
76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fclose(fp);
78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
8084616f8317554be7542b2e89b69f4129995cb03bshemmingerstatic void read_mroute_list(FILE *ofp)
81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char buf[256];
83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *fp = fopen("/proc/net/ip_mr_cache", "r");
84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!fp)
86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return;
87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
88e588a7db167df75e659f99bd3b024eedafed62ccThomas Jarosch	if (!fgets(buf, sizeof(buf), fp)) {
89e588a7db167df75e659f99bd3b024eedafed62ccThomas Jarosch		fclose(fp);
9038c867d2a82d6f2b60450550fbaaadc5d9c77579Stephen Hemminger		return;
91e588a7db167df75e659f99bd3b024eedafed62ccThomas Jarosch	}
92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (fgets(buf, sizeof(buf), fp)) {
94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		inet_prefix maddr, msrc;
95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		unsigned pkts, b, w;
96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		int vifi;
97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		char oiflist[256];
98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		char sbuf[256];
99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		char mbuf[256];
100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		char obuf[256];
101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		oiflist[0] = 0;
103080b3ad42820e002b91ab4e3ddb728d2c6763b58Mark Borst		if (sscanf(buf, "%x%x%d%u%u%u %[^\n]",
104080b3ad42820e002b91ab4e3ddb728d2c6763b58Mark Borst			   maddr.data, msrc.data, &vifi,
105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			   &pkts, &b, &w, oiflist) < 6)
106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (vifi!=-1 && (vifi < 0 || vifi>31))
109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (filter_dev[0] && (vifi<0 || strcmp(filter_dev, viftable[vifi])))
112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (filter.mdst.family && inet_addr_match(&maddr, &filter.mdst, filter.mdst.bitlen))
114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (filter.msrc.family && inet_addr_match(&msrc, &filter.msrc, filter.msrc.bitlen))
116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
118ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger		snprintf(obuf, sizeof(obuf), "(%s, %s)",
119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			 format_host(AF_INET, 4, &msrc.data[0], sbuf, sizeof(sbuf)),
120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			 format_host(AF_INET, 4, &maddr.data[0], mbuf, sizeof(mbuf)));
121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(ofp, "%-32s Iif: ", obuf);
123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (vifi == -1)
125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(ofp, "unresolved ");
126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		else
127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(ofp, "%-10s ", viftable[vifi]);
128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
129aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (oiflist[0]) {
130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			char *next = NULL;
131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			char *p = oiflist;
132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			int ovifi, ottl;
133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(ofp, "Oifs: ");
135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			while (p) {
137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				next = strchr(p, ' ');
138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (next) {
139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					*next = 0;
140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					next++;
141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (sscanf(p, "%d:%d", &ovifi, &ottl)<2) {
143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					p = next;
144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					continue;
145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				p = next;
147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
148aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(ofp, "%s", viftable[ovifi]);
149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (ottl>1)
150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					fprintf(ofp, "(ttl %d) ", ovifi);
151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				else
152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					fprintf(ofp, " ");
153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (show_stats && b) {
157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(ofp, "%s  %u packets, %u bytes", _SL_, pkts, b);
158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (w)
159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(ofp, ", %u arrived on wrong iif.", w);
160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(ofp, "\n");
162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fclose(fp);
164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int mroute_list(int argc, char **argv)
168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (argc > 0) {
170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (strcmp(*argv, "iif") == 0) {
171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			strncpy(filter_dev, *argv, sizeof(filter_dev)-1);
173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "from") == 0) {
174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			get_prefix(&filter.msrc, *argv, AF_INET);
176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else {
177aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(*argv, "to") == 0) {
178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				NEXT_ARG();
179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (matches(*argv, "help") == 0)
181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				usage();
182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			get_prefix(&filter.mdst, *argv, AF_INET);
183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
184aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		argv++; argc--;
185aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
186aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	read_viftable();
188aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	read_mroute_list(stdout);
189aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_multiroute(int argc, char **argv)
193aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (argc < 1)
195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return mroute_list(0, NULL);
196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#if 0
197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (matches(*argv, "add") == 0)
198aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return mroute_modify(RTM_NEWADDR, argc-1, argv+1);
199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (matches(*argv, "delete") == 0)
200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return mroute_modify(RTM_DELADDR, argc-1, argv+1);
201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (matches(*argv, "get") == 0)
202aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return mroute_get(argc-1, argv+1);
203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif
204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    || matches(*argv, "lst") == 0)
206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return mroute_list(argc-1, argv+1);
207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (matches(*argv, "help") == 0)
208aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		usage();
209aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Command \"%s\" is unknown, try \"ip mroute help\".\n", *argv);
210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
212