1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * f_fw.c FW filter. 3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is free software; you can redistribute it and/or 5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * modify it under the terms of the GNU General Public License 6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * as published by the Free Software Foundation; either version 7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 2 of the License, or (at your option) any later version. 8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h> 14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdlib.h> 15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h> 16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <syslog.h> 17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fcntl.h> 18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h> 19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netinet/in.h> 20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h> 21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h> 22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/if.h> /* IFNAMSIZ */ 23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h" 24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tc_util.h" 25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void explain(void) 27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Usage: ... fw [ classid CLASSID ] [ police POLICE_SPEC ]\n"); 29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " POLICE_SPEC := ... look at TBF\n"); 30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " CLASSID := X:Y\n"); 31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n"); 32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) 35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_police tp; 37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tcmsg *t = NLMSG_DATA(n); 38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tail; 39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 mask = 0; 40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int mask_set = 0; 41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&tp, 0, sizeof(tp)); 43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (handle) { 45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *slash; 46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((slash = strchr(handle, '/')) != NULL) 47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *slash = '\0'; 48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&t->tcm_handle, handle, 0)) { 49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"handle\"\n"); 50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (slash) { 53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&mask, slash+1, 0)) { 54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"handle\" mask\n"); 55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat mask_set = 1; 58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc == 0) 62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail = NLMSG_TAIL(n); 65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); 66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (mask_set) 68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr32(n, MAX_MSG, TCA_FW_MASK, mask); 69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "classid") == 0 || 72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat matches(*argv, "flowid") == 0) { 73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned handle; 74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_tc_classid(&handle, *argv)) { 76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"classid\"\n"); 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 4096, TCA_FW_CLASSID, &handle, 4); 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "police") == 0) { 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (parse_police(&argc, &argv, TCA_FW_POLICE, n)) { 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"police\"\n"); 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "action") == 0) { 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (parse_action(&argc, &argv, TCA_FW_ACT, n)) { 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal fw \"action\"\n"); 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "indev") == 0) { 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char d[IFNAMSIZ+1]; 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(d, 0, sizeof (d)); 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argv++; 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc < 1) { 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal indev\n"); 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strncpy(d, *argv, sizeof (d) - 1); 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, TCA_FW_INDEV, d, strlen(d) + 1); 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "help") == 0) { 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain(); 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "What is \"%s\"?\n", *argv); 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain(); 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle) 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tb[TCA_FW_MAX+1]; 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (opt == NULL) 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(tb, TCA_FW_MAX, opt); 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (handle || tb[TCA_FW_MASK]) { 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 mark = 0, mask = 0; 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if(handle) 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat mark = handle; 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if(tb[TCA_FW_MASK] && 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (mask = *(__u32*)RTA_DATA(tb[TCA_FW_MASK])) != 0xFFFFFFFF) 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "handle 0x%x/0x%x ", mark, mask); 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "handle 0x%x ", handle); 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_FW_CLASSID]) { 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "classid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_FW_CLASSID]), b1)); 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_FW_POLICE]) 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tc_print_police(f, tb[TCA_FW_POLICE]); 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_FW_INDEV]) { 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *idev = tb[TCA_FW_INDEV]; 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "input dev %s ",(char *)RTA_DATA(idev)); 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_FW_ACT]) { 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\n"); 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tc_print_action(f, tb[TCA_FW_ACT]); 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct filter_util fw_filter_util = { 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .id = "fw", 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .parse_fopt = fw_parse_opt, 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .print_fopt = fw_print_opt, 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 163