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