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