1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * m_ipt.c iptables based targets 3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * utilities mostly ripped from iptables <duh, its the linux way> 4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is free software; you can distribute it and/or 6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * modify it under the terms of the GNU General Public License 7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * as published by the Free Software Foundation; either version 8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 2 of the License, or (at your option) any later version. 9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Authors: J Hadi Salim (hadi@cyberus.ca) 11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <syslog.h> 14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h> 15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netinet/in.h> 16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h> 17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/if.h> 18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <iptables.h> 19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/netfilter.h> 20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/netfilter_ipv4/ip_tables.h> 21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h" 22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tc_util.h" 23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/tc_act/tc_ipt.h> 24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h> 25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <dlfcn.h> 26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <getopt.h> 27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <errno.h> 28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h> 29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netdb.h> 30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdlib.h> 31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <ctype.h> 32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdarg.h> 33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h> 34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fcntl.h> 35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/wait.h> 36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *pname = "tc-ipt"; 38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *tname = "mangle"; 39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *pversion = "0.1"; 40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *ipthooks[] = { 42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "NF_IP_PRE_ROUTING", 43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "NF_IP_LOCAL_IN", 44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "NF_IP_FORWARD", 45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "NF_IP_LOCAL_OUT", 46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "NF_IP_POST_ROUTING", 47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct option original_opts[] = { 50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat {"jump", 1, 0, 'j'}, 51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat {0, 0, 0, 0} 52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct iptables_target *t_list = NULL; 55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct option *opts = original_opts; 56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic unsigned int global_option_offset = 0; 57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define OPTION_OFFSET 256 58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatchar *lib_dir; 60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid 62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatregister_target(struct iptables_target *me) 63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* fprintf(stderr, "\nDummy register_target %s \n", me->name); 65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat*/ 66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat me->next = t_list; 67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t_list = me; 68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid 72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatxtables_register_target(struct iptables_target *me) 73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat me->next = t_list; 75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t_list = me; 76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatexit_tryhelp(int status) 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n", 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat pname, pname); 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(status); 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatexit_error(enum exittype status, char *msg, ...) 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat va_list args; 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat va_start(args, msg); 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "%s v%s: ", pname, pversion); 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat vfprintf(stderr, msg, args); 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat va_end(args); 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "\n"); 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (status == PARAMETER_PROBLEM) 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit_tryhelp(status); 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (status == VERSION_PROBLEM) 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "Perhaps iptables or your kernel needs to be upgraded.\n"); 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(status); 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* stolen from iptables 1.2.11 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San MehatThey should really have them as a library so i can link to them 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San MehatEmail them next time i remember 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat*/ 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatchar * 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehataddr_to_dotted(const struct in_addr *addrp) 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat static char buf[20]; 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const unsigned char *bytep; 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat bytep = (const unsigned char *) &(addrp->s_addr); 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]); 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return buf; 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint string_to_number_ll(const char *s, unsigned long long min, 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long long max, 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long long *ret) 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long long number; 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *end; 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* Handle hex, octal, etc. */ 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat errno = 0; 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat number = strtoull(s, &end, 0); 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (*end == '\0' && end != s) { 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* we parsed a number, let's see if we want this */ 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (errno != ERANGE && min <= number && (!max || number <= max)) { 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *ret = number; 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint string_to_number_l(const char *s, unsigned long min, unsigned long max, 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long *ret) 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int result; 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long long number; 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat result = string_to_number_ll(s, min, max, &number); 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *ret = (unsigned long)number; 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return result; 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint string_to_number(const char *s, unsigned int min, unsigned int max, 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned int *ret) 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int result; 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned long number; 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat result = string_to_number_l(s, min, max, &number); 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *ret = (unsigned int)number; 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return result; 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void free_opts(struct option *local_opts) 165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (local_opts != original_opts) { 167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free(local_opts); 168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat opts = original_opts; 169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat global_option_offset = 0; 170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct option * 174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatmerge_options(struct option *oldopts, const struct option *newopts, 175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned int *option_offset) 176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct option *merge; 178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned int num_old, num_new, i; 179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (num_old = 0; oldopts[num_old].name; num_old++) ; 181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (num_new = 0; newopts[num_new].name; num_new++) ; 182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *option_offset = global_option_offset + OPTION_OFFSET; 184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat merge = malloc(sizeof (struct option) * (num_new + num_old + 1)); 186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(merge, oldopts, num_old * sizeof (struct option)); 187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i = 0; i < num_new; i++) { 188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat merge[num_old + i] = newopts[i]; 189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat merge[num_old + i].val += *option_offset; 190dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 191dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(merge + num_old + num_new, 0, sizeof (struct option)); 192dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 193dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return merge; 194dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 195dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 196dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void * 197dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatfw_calloc(size_t count, size_t size) 198dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 199dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *p; 200dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 201dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((p = (void *) calloc(count, size)) == NULL) { 202dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat perror("iptables: calloc failed"); 203dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 204dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 205dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return p; 206dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 207dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 208dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct iptables_target * 209dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatfind_t(char *name) 210dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 211dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct iptables_target *m; 212dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (m = t_list; m; m = m->next) { 213dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(m->name, name) == 0) 214dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return m; 215dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 216dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 217dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return NULL; 218dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 219dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 220dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct iptables_target * 221dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatget_target_name(const char *name) 222dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 223dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *handle; 224dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *error; 225dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *new_name, *lname; 226dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct iptables_target *m; 227dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char path[strlen(lib_dir) + sizeof ("/libipt_.so") + strlen(name)]; 228dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 229dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifdef NO_SHARED_LIBS 230dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return NULL; 231dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif 232dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 233dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat new_name = malloc(strlen(name) + 1); 234dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lname = malloc(strlen(name) + 1); 235dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (new_name) 236dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(new_name, '\0', strlen(name) + 1); 237dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 238dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit_error(PARAMETER_PROBLEM, "get_target_name"); 239dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 240dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lname) 241dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(lname, '\0', strlen(name) + 1); 242dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 243dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit_error(PARAMETER_PROBLEM, "get_target_name"); 244dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 245dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcpy(new_name, name); 246dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcpy(lname, name); 247dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 248dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (isupper(lname[0])) { 249dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 250dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i = 0; i < strlen(name); i++) { 251dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lname[i] = tolower(lname[i]); 252dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 253dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 254dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 255dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (islower(new_name[0])) { 256dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 257dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i = 0; i < strlen(new_name); i++) { 258dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat new_name[i] = toupper(new_name[i]); 259dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 260dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 261dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 262dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* try libxt_xx first */ 263dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(path, "%s/libxt_%s.so", lib_dir, new_name); 264dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat handle = dlopen(path, RTLD_LAZY); 265dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!handle) { 266dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* try libipt_xx next */ 267dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(path, "%s/libipt_%s.so", lib_dir, new_name); 268dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat handle = dlopen(path, RTLD_LAZY); 269dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 270dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!handle) { 271dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(path, "%s/libxt_%s.so", lib_dir , lname); 272dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat handle = dlopen(path, RTLD_LAZY); 273dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 274dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 275dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!handle) { 276dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(path, "%s/libipt_%s.so", lib_dir , lname); 277dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat handle = dlopen(path, RTLD_LAZY); 278dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 279dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* ok, lets give up .. */ 280dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!handle) { 281dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fputs(dlerror(), stderr); 282dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("\n"); 283dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free(new_name); 284dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return NULL; 285dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 286dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 287dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 288dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m = dlsym(handle, new_name); 289dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((error = dlerror()) != NULL) { 290dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m = (struct iptables_target *) dlsym(handle, lname); 291dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((error = dlerror()) != NULL) { 292dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m = find_t(new_name); 293dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL == m) { 294dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m = find_t(lname); 295dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL == m) { 296dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fputs(error, stderr); 297dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "\n"); 298dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dlclose(handle); 299dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free(new_name); 300dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return NULL; 301dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 302dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 303dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 304dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 305dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 306dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free(new_name); 307dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return m; 308dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 309dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 310dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 311dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct in_addr *dotted_to_addr(const char *dotted) 312dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 313dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat static struct in_addr addr; 314dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned char *addrp; 315dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *p, *q; 316dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned int onebyte; 317dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 318dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[20]; 319dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 320dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* copy dotted string, because we need to modify it */ 321dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strncpy(buf, dotted, sizeof (buf) - 1); 322dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addrp = (unsigned char *) &(addr.s_addr); 323dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 324dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p = buf; 325dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i = 0; i < 3; i++) { 326dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((q = strchr(p, '.')) == NULL) 327dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return (struct in_addr *) NULL; 328dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 329dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *q = '\0'; 330dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (string_to_number(p, 0, 255, &onebyte) == -1) 331dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return (struct in_addr *) NULL; 332dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 333dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addrp[i] = (unsigned char) onebyte; 334dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p = q + 1; 335dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 336dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 337dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* we've checked 3 bytes, now we check the last one */ 338dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (string_to_number(p, 0, 255, &onebyte) == -1) 339dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return (struct in_addr *) NULL; 340dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 341dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addrp[3] = (unsigned char) onebyte; 342dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 343dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return &addr; 344dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 345dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 346dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void set_revision(char *name, u_int8_t revision) 347dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 348dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* Old kernel sources don't have ".revision" field, 349dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * but we stole a byte from name. */ 350dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat name[IPT_FUNCTION_MAXNAMELEN - 2] = '\0'; 351dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat name[IPT_FUNCTION_MAXNAMELEN - 1] = revision; 352dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 353dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 354dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 355dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * we may need to check for version mismatch 356dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat*/ 357dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 358dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatbuild_st(struct iptables_target *target, struct ipt_entry_target *t) 359dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 360dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned int nfcache = 0; 361dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 362dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (target) { 363dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat size_t size; 364dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 365dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat size = 366dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat IPT_ALIGN(sizeof (struct ipt_entry_target)) + target->size; 367dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 368dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL == t) { 369dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat target->t = fw_calloc(1, size); 370dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat target->t->u.target_size = size; 371dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 372dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (target->init != NULL) 373dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat target->init(target->t, &nfcache); 374dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat set_revision(target->t->u.user.name, target->revision); 375dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 376dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat target->t = t; 377dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 378dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcpy(target->t->u.user.name, target->name); 379dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 380dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 381dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 382dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 383dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 384dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 385dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int parse_ipt(struct action_util *a,int *argc_p, 386dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char ***argv_p, int tca_id, struct nlmsghdr *n) 387dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 388dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct iptables_target *m = NULL; 389dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ipt_entry fw; 390dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tail; 391dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int c; 392dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int rargc = *argc_p; 393dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char **argv = *argv_p; 394dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int argc = 0, iargc = 0; 395dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char k[16]; 396dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int res = -1; 397dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int size = 0; 398dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int iok = 0, ok = 0; 399dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 hook = 0, index = 0; 400dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = 0; 401dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 402dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lib_dir = getenv("IPTABLES_LIB_DIR"); 403dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!lib_dir) 404dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lib_dir = IPT_LIB_DIR; 405dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 406dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 407dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 408dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i = 0; i < rargc; i++) { 409dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL == argv[i] || 0 == strcmp(argv[i], "action")) { 410dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 411dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 412dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 413dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iargc = argc = i; 414dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 415dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 416dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc <= 2) { 417dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr,"bad arguements to ipt %d vs %d \n", argc, rargc); 418dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 419dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 420dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 421dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (1) { 422dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat c = getopt_long(argc, argv, "j:", opts, NULL); 423dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (c == -1) 424dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 425dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat switch (c) { 426dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case 'j': 427dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m = get_target_name(optarg); 428dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL != m) { 429dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 430dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (0 > build_st(m, NULL)) { 431dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" %s error \n", m->name); 432dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 433dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 434dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat opts = 435dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat merge_options(opts, m->extra_opts, 436dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat &m->option_offset); 437dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 438dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr," failed to find target %s\n\n", optarg); 439dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 440dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 441dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ok++; 442dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 443dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 444dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat default: 445dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&fw, 0, sizeof (fw)); 446dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (m) { 447dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->parse(c - m->option_offset, argv, 0, 448dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat &m->tflags, NULL, &m->t); 449dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 450dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr," failed to find target %s\n\n", optarg); 451dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 452dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 453dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 454dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ok++; 455dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 456dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 457dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 458dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 459dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 460dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (iargc > optind) { 461dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(argv[optind], "index") == 0) { 462dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&index, argv[optind + 1], 10)) { 463dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"index\"\n"); 464dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free_opts(opts); 465dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 466dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 467dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iok++; 468dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 469dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat optind += 2; 470dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 471dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 472dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 473dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ok && !iok) { 474dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr," ipt Parser BAD!! (%s)\n", *argv); 475dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 476dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 477dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 478dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* check that we passed the correct parameters to the target */ 479dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (m) 480dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->final_check(m->tflags); 481dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 482dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 483dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tcmsg *t = NLMSG_DATA(n); 484dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (t->tcm_parent != TC_H_ROOT 485dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat && t->tcm_parent == TC_H_MAJ(TC_H_INGRESS)) { 486dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat hook = NF_IP_PRE_ROUTING; 487dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 488dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat hook = NF_IP_POST_ROUTING; 489dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 490dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 491dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 492dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail = NLMSG_TAIL(n); 493dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, tca_id, NULL, 0); 494dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stdout, "tablename: %s hook: %s\n ", tname, ipthooks[hook]); 495dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stdout, "\ttarget: "); 496dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 497dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (m) 498dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->print(NULL, m->t, 0); 499dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stdout, " index %d\n", index); 500dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 501dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strlen(tname) > 16) { 502dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat size = 16; 503dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat k[15] = 0; 504dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 505dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat size = 1 + strlen(tname); 506dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 507dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strncpy(k, tname, size); 508dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 509dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, TCA_IPT_TABLE, k, size); 510dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, TCA_IPT_HOOK, &hook, 4); 511dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, TCA_IPT_INDEX, &index, 4); 512dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (m) 513dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, TCA_IPT_TARG, m->t, m->t->u.target_size); 514dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 515dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 516dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc -= optind; 517dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argv += optind; 518dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argc_p = rargc - iargc; 519dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argv_p = argv; 520dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 521dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat optind = 0; 522dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free_opts(opts); 523dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* Clear flags if target will be used again */ 524dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->tflags=0; 525dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->used=0; 526dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* Free allocated memory */ 527dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (m->t) 528dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free(m->t); 529dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 530dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 531dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 532dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 533dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 534dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 535dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int 536dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatprint_ipt(struct action_util *au,FILE * f, struct rtattr *arg) 537dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 538dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tb[TCA_IPT_MAX + 1]; 539dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ipt_entry_target *t = NULL; 540dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 541dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (arg == NULL) 542dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 543dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 544dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lib_dir = getenv("IPTABLES_LIB_DIR"); 545dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!lib_dir) 546dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lib_dir = IPT_LIB_DIR; 547dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 548dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(tb, TCA_IPT_MAX, arg); 549dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 550dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_TABLE] == NULL) { 551dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "[NULL ipt table name ] assuming mangle "); 552dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 553dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "tablename: %s ", 554dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (char *) RTA_DATA(tb[TCA_IPT_TABLE])); 555dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 556dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 557dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_HOOK] == NULL) { 558dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "[NULL ipt hook name ]\n "); 559dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 560dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 561dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 hook; 562dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat hook = *(__u32 *) RTA_DATA(tb[TCA_IPT_HOOK]); 563dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " hook: %s \n", ipthooks[hook]); 564dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 565dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 566dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_TARG] == NULL) { 567dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\t[NULL ipt target parameters ] \n"); 568dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 569dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 570dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct iptables_target *m = NULL; 571dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t = RTA_DATA(tb[TCA_IPT_TARG]); 572dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m = get_target_name(t->u.user.name); 573dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL != m) { 574dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (0 > build_st(m, t)) { 575dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " %s error \n", m->name); 576dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 577dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 578dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 579dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat opts = 580dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat merge_options(opts, m->extra_opts, 581dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat &m->option_offset); 582dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 583dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " failed to find target %s\n\n", 584dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t->u.user.name); 585dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 586dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 587dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\ttarget "); 588dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->print(NULL, m->t, 0); 589dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_INDEX] == NULL) { 590dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " [NULL ipt target index ]\n"); 591dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 592dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 index; 593dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat index = *(__u32 *) RTA_DATA(tb[TCA_IPT_INDEX]); 594dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " \n\tindex %d", index); 595dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 596dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 597dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_CNT]) { 598dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cnt *c = RTA_DATA(tb[TCA_IPT_CNT]);; 599dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " ref %d bind %d", c->refcnt, c->bindcnt); 600dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 601dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats) { 602dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_TM]) { 603dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tcf_t *tm = RTA_DATA(tb[TCA_IPT_TM]); 604dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_tm(f,tm); 605dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 606dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 607dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " \n"); 608dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 609dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 610dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free_opts(opts); 611dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 612dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 613dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 614dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 615dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct action_util ipt_action_util = { 616dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .id = "ipt", 617dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .parse_aopt = parse_ipt, 618dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .print_aopt = print_ipt, 619dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 620dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 621