1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/*
2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * tc.c		"tc" utility frontend.
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 * Fixes:
12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Petri Mattila <petri@prihateam.fi> 990308: wrong memset's resulted in faults
14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */
15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h>
17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h>
18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h>
19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h>
20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h>
21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <dlfcn.h>
22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h>
23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h>
24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h>
25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h>
26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <errno.h>
27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "SNAPSHOT.h"
29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h"
30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_util.h"
31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_common.h"
32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint show_stats = 0;
34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint show_details = 0;
35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint show_raw = 0;
3644dcfe820185590f04c9f5f18579d08532fc1a4bStephen Hemmingerint show_pretty = 0;
3744dcfe820185590f04c9f5f18579d08532fc1a4bStephen Hemminger
38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint resolve_hosts = 0;
393ea2bf45b0661bd3be3a5695043d0d4ea67224bdosdl.net!shemmingerint use_iec = 0;
4008856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemmingerint force = 0;
417901660a0de70528c50e812f76df9ba224680258osdl.net!shemmingerstruct rtnl_handle rth;
42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
43f453a0d451706555690673e12b70069d84d5cf01shemmingerstatic void *BODY = NULL;	/* cached handle dlopen(NULL) */
44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic struct qdisc_util * qdisc_list;
45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic struct filter_util * filter_list;
46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
478e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat#ifdef ANDROID
488e86eb94ac8221c8d8c0a08a777c16da87169135San Mehatextern struct qdisc_util cbq_qdisc_util;
49926d4a2528aabf58a7be0efcffbafa795b5ad30cSan Mehatextern struct qdisc_util htb_qdisc_util;
50ec731b7f59d21a62b72823c29d621bf77a827be1San Mehatextern struct qdisc_util ingress_qdisc_util;
518e86eb94ac8221c8d8c0a08a777c16da87169135San Mehatextern struct filter_util u32_filter_util;
528e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat#endif
538e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat
54ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemmingerstatic int print_noqopt(struct qdisc_util *qu, FILE *f,
551798c9d5a421f4c8136c8d887feb5c5b126643b9osdl.net!shemminger			struct rtattr *opt)
56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (opt && RTA_PAYLOAD(opt))
58ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger		fprintf(f, "[Unknown qdisc, optlen=%u] ",
59bb6a21a4fcaf400ca4766eea6064f2df30393d1eosdl.net!shemminger			(unsigned) RTA_PAYLOAD(opt));
60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int parse_noqopt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (argc) {
66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "Unknown qdisc \"%s\", hence option \"%s\" is unparsable\n", qu->id, *argv);
67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int print_nofopt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 fhandle)
73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (opt && RTA_PAYLOAD(opt))
75ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger		fprintf(f, "fh %08x [Unknown filter, optlen=%u] ",
76bb6a21a4fcaf400ca4766eea6064f2df30393d1eosdl.net!shemminger			fhandle, (unsigned) RTA_PAYLOAD(opt));
77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	else if (fhandle)
78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(f, "fh %08x ", fhandle);
79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int parse_nofopt(struct filter_util *qu, char *fhandle, int argc, char **argv, struct nlmsghdr *n)
83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	__u32 handle;
85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (argc) {
87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "Unknown filter \"%s\", hence option \"%s\" is unparsable\n", qu->id, *argv);
88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fhandle) {
91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		struct tcmsg *t = NLMSG_DATA(n);
92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (get_u32(&handle, fhandle, 16)) {
93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "Unparsable filter ID \"%s\"\n", fhandle);
94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		t->tcm_handle = handle;
97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
1014094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerstruct qdisc_util *get_qdisc_kind(const char *str)
102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	void *dlh;
104aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char buf[256];
105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct qdisc_util *q;
106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
1078e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat#ifdef ANDROID
1088e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat	if (!strcmp(str, "cbq"))
1098e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat		return &cbq_qdisc_util;
110926d4a2528aabf58a7be0efcffbafa795b5ad30cSan Mehat	else if (!strcmp(str, "htb"))
111926d4a2528aabf58a7be0efcffbafa795b5ad30cSan Mehat		return &htb_qdisc_util;
112ec731b7f59d21a62b72823c29d621bf77a827be1San Mehat	else if (!strcmp(str, "ingress"))
113ec731b7f59d21a62b72823c29d621bf77a827be1San Mehat		return &ingress_qdisc_util;
1148e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat	else {
115926d4a2528aabf58a7be0efcffbafa795b5ad30cSan Mehat		fprintf(stderr, "Android does not support qdisc '%s'\n", str);
1168e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat		return NULL;
1178e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat	}
1188e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat#endif
119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (q = qdisc_list; q; q = q->next)
120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (strcmp(q->id, str) == 0)
121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return q;
122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
123aa27f88c8444ad6a87ebb563d6ffacb4fe95d87cStephen Hemminger	snprintf(buf, sizeof(buf), "%s/q_%s.so", get_tc_lib(), str);
124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	dlh = dlopen(buf, RTLD_LAZY);
125b7a45150854a59bc95f65ec79af35dd390f05a50osdl.net!shemminger	if (!dlh) {
126b7a45150854a59bc95f65ec79af35dd390f05a50osdl.net!shemminger		/* look in current binary, only open once */
127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dlh = BODY;
128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (dlh == NULL) {
129aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			dlh = BODY = dlopen(NULL, RTLD_LAZY);
130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (dlh == NULL)
131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				goto noexist;
132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
13595812b56a5a66e7e9a21744cfe8bc0bb9791ea98net[shemminger]!kaber	snprintf(buf, sizeof(buf), "%s_qdisc_util", str);
136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q = dlsym(dlh, buf);
137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (q == NULL)
138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		goto noexist;
139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerreg:
141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q->next = qdisc_list;
142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	qdisc_list = q;
143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return q;
144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingernoexist:
146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q = malloc(sizeof(*q));
147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (q) {
1481798c9d5a421f4c8136c8d887feb5c5b126643b9osdl.net!shemminger
149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		memset(q, 0, sizeof(*q));
1501798c9d5a421f4c8136c8d887feb5c5b126643b9osdl.net!shemminger		q->id = strcpy(malloc(strlen(str)+1), str);
151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		q->parse_qopt = parse_noqopt;
152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		q->print_qopt = print_noqopt;
153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		goto reg;
154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return q;
156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
1594094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerstruct filter_util *get_filter_kind(const char *str)
160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	void *dlh;
162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char buf[256];
163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct filter_util *q;
1648e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat#ifdef ANDROID
1658e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat	if (!strcmp(str, "u32"))
1668e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat		return &u32_filter_util;
1678e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat	else {
168926d4a2528aabf58a7be0efcffbafa795b5ad30cSan Mehat		fprintf(stderr, "Android does not support filter '%s'\n", str);
1698e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat		return NULL;
1708e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat	}
1718e86eb94ac8221c8d8c0a08a777c16da87169135San Mehat#endif
172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (q = filter_list; q; q = q->next)
174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (strcmp(q->id, str) == 0)
175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return q;
176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
177aa27f88c8444ad6a87ebb563d6ffacb4fe95d87cStephen Hemminger	snprintf(buf, sizeof(buf), "%s/f_%s.so", get_tc_lib(), str);
178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	dlh = dlopen(buf, RTLD_LAZY);
179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (dlh == NULL) {
180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dlh = BODY;
181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (dlh == NULL) {
182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			dlh = BODY = dlopen(NULL, RTLD_LAZY);
183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (dlh == NULL)
184aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				goto noexist;
185aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
186aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
18895812b56a5a66e7e9a21744cfe8bc0bb9791ea98net[shemminger]!kaber	snprintf(buf, sizeof(buf), "%s_filter_util", str);
189aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q = dlsym(dlh, buf);
190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (q == NULL)
191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		goto noexist;
192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
193aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerreg:
194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q->next = filter_list;
195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	filter_list = q;
196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return q;
197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingernoexist:
198aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q = malloc(sizeof(*q));
199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (q) {
200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		memset(q, 0, sizeof(*q));
201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		strncpy(q->id, str, 15);
202aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		q->parse_fopt = parse_nofopt;
203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		q->print_fopt = print_nofopt;
204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		goto reg;
205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return q;
207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
208aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
209c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemmingerstatic void usage(void)
210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n"
2126644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#ifdef ANDROID
2136644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat			"       tc [-force]\n"
2146644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#else
21510494d2724cac05d6a8a352205da18b86787eabaPetr Jediný			"       tc [-force] -batch filename\n"
2166644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#endif
2175bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	                "where  OBJECT := { qdisc | class | filter | action | monitor }\n"
21810494d2724cac05d6a8a352205da18b86787eabaPetr Jediný	                "       OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -b[atch] [filename] }\n");
219c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger}
220c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
221c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemmingerstatic int do_cmd(int argc, char **argv)
222c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger{
223c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (matches(*argv, "qdisc") == 0)
224c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return do_qdisc(argc-1, argv+1);
225c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
226c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (matches(*argv, "class") == 0)
227c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return do_class(argc-1, argv+1);
228c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
229c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (matches(*argv, "filter") == 0)
230c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return do_filter(argc-1, argv+1);
231c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
232c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (matches(*argv, "actions") == 0)
233c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return do_action(argc-1, argv+1);
234c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
2355bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	if (matches(*argv, "monitor") == 0)
2365bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		return do_tcmonitor(argc-1, argv+1);
2375bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
238c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (matches(*argv, "help") == 0) {
239c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		usage();
240c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return 0;
241c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	}
242ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
243ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	fprintf(stderr, "Object \"%s\" is unknown, try \"tc help\".\n",
244c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		*argv);
245044ebf35b10a462005354edcf3de17a79722035aosdl.net!shemminger	return -1;
246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
2486644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#ifndef ANDROID
249c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemmingerstatic int batch(const char *name)
250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
251c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	char *line = NULL;
252c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	size_t len = 0;
25308856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger	int ret = 0;
254c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
255dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger	if (name && strcmp(name, "-") != 0) {
256c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		if (freopen(name, "r", stdin) == NULL) {
25784d66882aa068ba0cb5a63a4915648d70dbcda45Stephen Hemminger			fprintf(stderr, "Cannot open file \"%s\" for reading: %s\n",
258c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger				name, strerror(errno));
259044ebf35b10a462005354edcf3de17a79722035aosdl.net!shemminger			return -1;
260aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
261c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	}
262c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
263c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	tc_core_init();
264c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
265c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (rtnl_open(&rth, 0) < 0) {
266c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		fprintf(stderr, "Cannot open rtnetlink\n");
267c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return -1;
268c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	}
269c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
270351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	cmdlineno = 0;
27108856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger	while (getcmdline(&line, &len, stdin) != -1) {
27208856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		char *largv[100];
27308856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		int largc;
274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
275c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		largc = makeargs(line, largv, 100);
27608856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		if (largc == 0)
27708856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger			continue;	/* blank line */
278aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
27908856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		if (do_cmd(largc, largv)) {
280351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			fprintf(stderr, "Command failed %s:%d\n", name, cmdlineno);
28108856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger			ret = 1;
28208856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger			if (!force)
28308856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger				break;
284aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
285c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	}
2868ed63ab1f1283b2c63355fb7c1e80abead4b9399shemminger	if (line)
2878ed63ab1f1283b2c63355fb7c1e80abead4b9399shemminger		free(line);
2887901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger
289c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	rtnl_close(&rth);
290c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	return ret;
291c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger}
2926644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#endif
293c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
294c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemmingerint main(int argc, char **argv)
295c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger{
296c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	int ret;
2976644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#ifndef ANDROID
298dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger	int do_batching = 0;
29908856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger	char *batchfile = NULL;
3006644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#endif
301aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
302aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (argc > 1) {
303aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (argv[1][0] != '-')
304aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
305aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(argv[1], "-stats") == 0 ||
3063ea2bf45b0661bd3be3a5695043d0d4ea67224bdosdl.net!shemminger			 matches(argv[1], "-statistics") == 0) {
307aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			++show_stats;
308aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(argv[1], "-details") == 0) {
309aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			++show_details;
310aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(argv[1], "-raw") == 0) {
311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			++show_raw;
31244dcfe820185590f04c9f5f18579d08532fc1a4bStephen Hemminger		} else if (matches(argv[1], "-pretty") == 0) {
31344dcfe820185590f04c9f5f18579d08532fc1a4bStephen Hemminger			++show_pretty;
314aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(argv[1], "-Version") == 0) {
315aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf("tc utility, iproute2-ss%s\n", SNAPSHOT);
316044ebf35b10a462005354edcf3de17a79722035aosdl.net!shemminger			return 0;
3173ea2bf45b0661bd3be3a5695043d0d4ea67224bdosdl.net!shemminger		} else if (matches(argv[1], "-iec") == 0) {
3183ea2bf45b0661bd3be3a5695043d0d4ea67224bdosdl.net!shemminger			++use_iec;
319aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(argv[1], "-help") == 0) {
320aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			usage();
321c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger			return 0;
32208856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		} else if (matches(argv[1], "-force") == 0) {
32308856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger			++force;
3246644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#ifndef ANDROID
325c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		} else 	if (matches(argv[1], "-batch") == 0) {
326dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger			do_batching = 1;
327dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger			if (argc > 2)
328dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger				batchfile = argv[2];
32908856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger			argc--;	argv++;
3306644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#endif
331aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else {
332aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "Option \"%s\" is unknown, try \"tc -help\".\n", argv[1]);
333044ebf35b10a462005354edcf3de17a79722035aosdl.net!shemminger			return -1;
334aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
335aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		argc--;	argv++;
336aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
3376644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#ifndef ANDROID
338dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger	if (do_batching)
33908856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		return batch(batchfile);
3406644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#endif
34108856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger
342c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (argc <= 1) {
343c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		usage();
344c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return 0;
345c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	}
346c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
347aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	tc_core_init();
3487901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger	if (rtnl_open(&rth, 0) < 0) {
3497901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger		fprintf(stderr, "Cannot open rtnetlink\n");
3507901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger		exit(1);
3517901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger	}
352aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
353c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	ret = do_cmd(argc-1, argv+1);
3547901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger	rtnl_close(&rth);
355c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
356c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	return ret;
357aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
358