1/*
2 * q_dsmark.c		Differentiated Services field marking.
3 *
4 * Hacked 1998,1999 by Werner Almesberger, EPFL ICA
5 *
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <unistd.h>
11#include <syslog.h>
12#include <fcntl.h>
13#include <sys/socket.h>
14#include <netinet/in.h>
15#include <arpa/inet.h>
16#include <string.h>
17
18#include "utils.h"
19#include "tc_util.h"
20
21
22#define usage() return(-1)
23
24
25static void explain(void)
26{
27	fprintf(stderr,"Usage: dsmark indices INDICES [ default_index "
28	    "DEFAULT_INDEX ] [ set_tc_index ]\n");
29}
30
31
32static int dsmark_parse_opt(struct qdisc_util *qu, int argc, char **argv,
33    struct nlmsghdr *n)
34{
35	struct rtattr *tail;
36	__u16 ind;
37	char *end;
38	int dflt,set_tc_index;
39
40	ind = set_tc_index = 0;
41	dflt = -1;
42	while (argc > 0) {
43		if (!strcmp(*argv,"indices")) {
44			NEXT_ARG();
45			ind = strtoul(*argv,&end,0);
46			if (*end) {
47				explain();
48				return -1;
49			}
50		}
51		else if (!strcmp(*argv,"default_index") || !strcmp(*argv,
52		    "default")) {
53			NEXT_ARG();
54			dflt = strtoul(*argv,&end,0);
55			if (*end) {
56				explain();
57				return -1;
58			}
59		}
60		else if (!strcmp(*argv,"set_tc_index")) {
61			set_tc_index = 1;
62		}
63		else {
64			explain();
65			return -1;
66		}
67		argc--;
68		argv++;
69	}
70	if (!ind) {
71		explain();
72		return -1;
73	}
74	tail = (struct rtattr *) (((void *) n)+NLMSG_ALIGN(n->nlmsg_len));
75	addattr_l(n,1024,TCA_OPTIONS,NULL,0);
76	addattr_l(n,1024,TCA_DSMARK_INDICES,&ind,sizeof(ind));
77	if (dflt != -1) {
78	    __u16 tmp = dflt;
79
80	    addattr_l(n,1024,TCA_DSMARK_DEFAULT_INDEX,&tmp,sizeof(tmp));
81	}
82	if (set_tc_index) addattr_l(n,1024,TCA_DSMARK_SET_TC_INDEX,NULL,0);
83	tail->rta_len = (((void *) n)+n->nlmsg_len)-(void *) tail;
84	return 0;
85}
86
87
88static void explain_class(void)
89{
90	fprintf(stderr, "Usage: ... dsmark [ mask MASK ] [ value VALUE ]\n");
91}
92
93
94static int dsmark_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
95   struct nlmsghdr *n)
96{
97	struct rtattr *tail;
98	__u8 tmp;
99	char *end;
100
101	tail = (struct rtattr *) (((void *) n)+NLMSG_ALIGN(n->nlmsg_len));
102	addattr_l(n,1024,TCA_OPTIONS,NULL,0);
103	while (argc > 0) {
104		if (!strcmp(*argv,"mask")) {
105			NEXT_ARG();
106			tmp = strtoul(*argv,&end,0);
107			if (*end) {
108				explain_class();
109				return -1;
110			}
111			addattr_l(n,1024,TCA_DSMARK_MASK,&tmp,1);
112		}
113		else if (!strcmp(*argv,"value")) {
114			NEXT_ARG();
115			tmp = strtoul(*argv,&end,0);
116			if (*end) {
117				explain_class();
118				return -1;
119			}
120			addattr_l(n,1024,TCA_DSMARK_VALUE,&tmp,1);
121		}
122		else {
123			explain_class();
124			return -1;
125		}
126		argc--;
127		argv++;
128	}
129	tail->rta_len = (((void *) n)+n->nlmsg_len)-(void *) tail;
130	return 0;
131}
132
133
134
135static int dsmark_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
136{
137	struct rtattr *tb[TCA_DSMARK_MAX+1];
138
139	if (!opt) return 0;
140	memset(tb, 0, sizeof(tb));
141	parse_rtattr(tb, TCA_DSMARK_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt));
142	if (tb[TCA_DSMARK_MASK]) {
143		if (!RTA_PAYLOAD(tb[TCA_DSMARK_MASK]))
144			fprintf(stderr,"dsmark: empty mask\n");
145		else fprintf(f,"mask 0x%02x ",
146			    *(__u8 *) RTA_DATA(tb[TCA_DSMARK_MASK]));
147	}
148	if (tb[TCA_DSMARK_VALUE]) {
149		if (!RTA_PAYLOAD(tb[TCA_DSMARK_VALUE]))
150			fprintf(stderr,"dsmark: empty value\n");
151		else fprintf(f,"value 0x%02x ",
152			    *(__u8 *) RTA_DATA(tb[TCA_DSMARK_VALUE]));
153	}
154	if (tb[TCA_DSMARK_INDICES]) {
155		if (RTA_PAYLOAD(tb[TCA_DSMARK_INDICES]) < sizeof(__u16))
156			fprintf(stderr,"dsmark: indices too short\n");
157		else fprintf(f,"indices 0x%04x ",
158			    *(__u16 *) RTA_DATA(tb[TCA_DSMARK_INDICES]));
159	}
160	if (tb[TCA_DSMARK_DEFAULT_INDEX]) {
161		if (RTA_PAYLOAD(tb[TCA_DSMARK_DEFAULT_INDEX]) < sizeof(__u16))
162			fprintf(stderr,"dsmark: default_index too short\n");
163		else fprintf(f,"default_index 0x%04x ",
164			    *(__u16 *) RTA_DATA(tb[TCA_DSMARK_DEFAULT_INDEX]));
165	}
166	if (tb[TCA_DSMARK_SET_TC_INDEX]) fprintf(f,"set_tc_index ");
167	return 0;
168}
169
170
171static int dsmark_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats)
172{
173	return 0;
174}
175
176
177struct qdisc_util dsmark_util = {
178	NULL,
179	"dsmark",
180	dsmark_parse_opt,
181	dsmark_print_opt,
182	dsmark_print_xstats,
183
184	dsmark_parse_class_opt,
185	dsmark_print_opt
186};
187