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 static void explain(void) 23 { 24 fprintf(stderr,"Usage: dsmark indices INDICES [ default_index " 25 "DEFAULT_INDEX ] [ set_tc_index ]\n"); 26 } 27 28 29 static int dsmark_parse_opt(struct qdisc_util *qu, int argc, char **argv, 30 struct nlmsghdr *n) 31 { 32 struct rtattr *tail; 33 __u16 ind; 34 char *end; 35 int dflt,set_tc_index; 36 37 ind = set_tc_index = 0; 38 dflt = -1; 39 while (argc > 0) { 40 if (!strcmp(*argv,"indices")) { 41 NEXT_ARG(); 42 ind = strtoul(*argv,&end,0); 43 if (*end) { 44 explain(); 45 return -1; 46 } 47 } 48 else if (!strcmp(*argv,"default_index") || !strcmp(*argv, 49 "default")) { 50 NEXT_ARG(); 51 dflt = strtoul(*argv,&end,0); 52 if (*end) { 53 explain(); 54 return -1; 55 } 56 } 57 else if (!strcmp(*argv,"set_tc_index")) { 58 set_tc_index = 1; 59 } 60 else { 61 explain(); 62 return -1; 63 } 64 argc--; 65 argv++; 66 } 67 if (!ind) { 68 explain(); 69 return -1; 70 } 71 tail = NLMSG_TAIL(n); 72 addattr_l(n,1024,TCA_OPTIONS,NULL,0); 73 addattr_l(n,1024,TCA_DSMARK_INDICES,&ind,sizeof(ind)); 74 if (dflt != -1) { 75 __u16 tmp = dflt; 76 77 addattr_l(n,1024,TCA_DSMARK_DEFAULT_INDEX,&tmp,sizeof(tmp)); 78 } 79 if (set_tc_index) addattr_l(n,1024,TCA_DSMARK_SET_TC_INDEX,NULL,0); 80 tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 81 return 0; 82 } 83 84 85 static void explain_class(void) 86 { 87 fprintf(stderr, "Usage: ... dsmark [ mask MASK ] [ value VALUE ]\n"); 88 } 89 90 91 static int dsmark_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, 92 struct nlmsghdr *n) 93 { 94 struct rtattr *tail; 95 __u8 tmp; 96 char *end; 97 98 tail = NLMSG_TAIL(n); 99 addattr_l(n,1024,TCA_OPTIONS,NULL,0); 100 while (argc > 0) { 101 if (!strcmp(*argv,"mask")) { 102 NEXT_ARG(); 103 tmp = strtoul(*argv,&end,0); 104 if (*end) { 105 explain_class(); 106 return -1; 107 } 108 addattr_l(n,1024,TCA_DSMARK_MASK,&tmp,1); 109 } 110 else if (!strcmp(*argv,"value")) { 111 NEXT_ARG(); 112 tmp = strtoul(*argv,&end,0); 113 if (*end) { 114 explain_class(); 115 return -1; 116 } 117 addattr_l(n,1024,TCA_DSMARK_VALUE,&tmp,1); 118 } 119 else { 120 explain_class(); 121 return -1; 122 } 123 argc--; 124 argv++; 125 } 126 tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 127 return 0; 128 } 129 130 131 132 static int dsmark_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) 133 { 134 struct rtattr *tb[TCA_DSMARK_MAX+1]; 135 136 if (!opt) return 0; 137 memset(tb, 0, sizeof(tb)); 138 parse_rtattr(tb, TCA_DSMARK_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)); 139 if (tb[TCA_DSMARK_MASK]) { 140 if (!RTA_PAYLOAD(tb[TCA_DSMARK_MASK])) 141 fprintf(stderr,"dsmark: empty mask\n"); 142 else fprintf(f,"mask 0x%02x ", 143 rta_getattr_u8(tb[TCA_DSMARK_MASK])); 144 } 145 if (tb[TCA_DSMARK_VALUE]) { 146 if (!RTA_PAYLOAD(tb[TCA_DSMARK_VALUE])) 147 fprintf(stderr,"dsmark: empty value\n"); 148 else fprintf(f,"value 0x%02x ", 149 rta_getattr_u8(tb[TCA_DSMARK_VALUE])); 150 } 151 if (tb[TCA_DSMARK_INDICES]) { 152 if (RTA_PAYLOAD(tb[TCA_DSMARK_INDICES]) < sizeof(__u16)) 153 fprintf(stderr,"dsmark: indices too short\n"); 154 else fprintf(f,"indices 0x%04x ", 155 rta_getattr_u16(tb[TCA_DSMARK_INDICES])); 156 } 157 if (tb[TCA_DSMARK_DEFAULT_INDEX]) { 158 if (RTA_PAYLOAD(tb[TCA_DSMARK_DEFAULT_INDEX]) < sizeof(__u16)) 159 fprintf(stderr,"dsmark: default_index too short\n"); 160 else fprintf(f,"default_index 0x%04x ", 161 rta_getattr_u16(tb[TCA_DSMARK_DEFAULT_INDEX])); 162 } 163 if (tb[TCA_DSMARK_SET_TC_INDEX]) fprintf(f,"set_tc_index "); 164 return 0; 165 } 166 167 168 struct qdisc_util dsmark_qdisc_util = { 169 .id = "dsmark", 170 .parse_qopt = dsmark_parse_opt, 171 .print_qopt = dsmark_print_opt, 172 .parse_copt = dsmark_parse_class_opt, 173 .print_copt = dsmark_print_opt, 174 }; 175