1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * m_xt.c xtables 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/*XXX: in the future (xtables 1.4.3?) get rid of everything tagged 14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * as TC_CONFIG_XT_H */ 15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <syslog.h> 17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h> 18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netinet/in.h> 19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h> 20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <net/if.h> 21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/netfilter.h> 22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/netfilter_ipv4/ip_tables.h> 23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <xtables.h> 24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h" 25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tc_util.h" 26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/tc_act/tc_ipt.h> 27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h> 28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <getopt.h> 29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <errno.h> 30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h> 31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netdb.h> 32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdlib.h> 33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <ctype.h> 34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdarg.h> 35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <limits.h> 36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h> 37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fcntl.h> 38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/wait.h> 39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifdef TC_CONFIG_XT_H 40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "xt-internal.h" 41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif 42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 431a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#ifndef ALIGN 441a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) 451a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) 461a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#endif 471a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *pname = "tc-ipt"; 49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *tname = "mangle"; 50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *pversion = "0.2"; 51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *ipthooks[] = { 53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "NF_IP_PRE_ROUTING", 54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "NF_IP_LOCAL_IN", 55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "NF_IP_FORWARD", 56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "NF_IP_LOCAL_OUT", 57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "NF_IP_POST_ROUTING", 58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct option original_opts[] = { 61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat {"jump", 1, 0, 'j'}, 62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat {0, 0, 0, 0} 63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct option *opts = original_opts; 66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic unsigned int global_option_offset = 0; 67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatchar *lib_dir; 68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatconst char *program_version = XTABLES_VERSION; 69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatconst char *program_name = "tc-ipt"; 70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct afinfo afinfo = { 71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .family = AF_INET, 72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .libprefix = "libxt_", 73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .ipproto = IPPROTO_IP, 74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .kmod = "ip_tables", 75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .so_rev_target = IPT_SO_GET_REVISION_TARGET, 76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define OPTION_OFFSET 256 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/*XXX: TC_CONFIG_XT_H */ 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void free_opts(struct option *local_opts) 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (local_opts != original_opts) { 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free(local_opts); 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat opts = original_opts; 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat global_option_offset = 0; 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/*XXX: TC_CONFIG_XT_H */ 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct option * 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatmerge_options(struct option *oldopts, const struct option *newopts, 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned int *option_offset) 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct option *merge; 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned int num_old, num_new, i; 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (num_old = 0; oldopts[num_old].name; num_old++) ; 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (num_new = 0; newopts[num_new].name; num_new++) ; 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *option_offset = global_option_offset + OPTION_OFFSET; 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat merge = malloc(sizeof (struct option) * (num_new + num_old + 1)); 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(merge, oldopts, num_old * sizeof (struct option)); 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i = 0; i < num_new; i++) { 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat merge[num_old + i] = newopts[i]; 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat merge[num_old + i].val += *option_offset; 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(merge + num_old + num_new, 0, sizeof (struct option)); 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return merge; 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/*XXX: TC_CONFIG_XT_H */ 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifndef TRUE 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define TRUE 1 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifndef FALSE 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define FALSE 0 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/*XXX: TC_CONFIG_XT_H */ 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatcheck_inverse(const char option[], int *invert, int *my_optind, int argc) 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (option && strcmp(option, "!") == 0) { 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (*invert) 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit_error(PARAMETER_PROBLEM, 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "Multiple `!' flags not allowed"); 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *invert = TRUE; 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (my_optind != NULL) { 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ++*my_optind; 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc && *my_optind > argc) 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit_error(PARAMETER_PROBLEM, 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "no argument following `!'"); 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return TRUE; 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return FALSE; 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/*XXX: TC_CONFIG_XT_H */ 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid exit_error(enum exittype status, const char *msg, ...) 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat va_list args; 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat va_start(args, msg); 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "%s v%s: ", pname, pversion); 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat vfprintf(stderr, msg, args); 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat va_end(args); 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "\n"); 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* On error paths, make sure that we don't leak memory */ 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(status); 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/*XXX: TC_CONFIG_XT_H */ 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void set_revision(char *name, u_int8_t revision) 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* Old kernel sources don't have ".revision" field, 163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * but we stole a byte from name. */ 164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat name[IPT_FUNCTION_MAXNAMELEN - 2] = '\0'; 165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat name[IPT_FUNCTION_MAXNAMELEN - 1] = revision; 166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * we may need to check for version mismatch 170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat*/ 171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatbuild_st(struct xtables_target *target, struct xt_entry_target *t) 173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat size_t size = 176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat XT_ALIGN(sizeof (struct xt_entry_target)) + target->size; 177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL == t) { 179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat target->t = fw_calloc(1, size); 180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat target->t->u.target_size = size; 181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcpy(target->t->u.user.name, target->name); 182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat set_revision(target->t->u.user.name, target->revision); 183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (target->init != NULL) 185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat target->init(target->t); 186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat target->t = t; 188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 190dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 191dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 192dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 193dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatinline void set_lib_dir(void) 194dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 195dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 196dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lib_dir = getenv("XTABLES_LIBDIR"); 197dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!lib_dir) { 198dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lib_dir = getenv("IPTABLES_LIB_DIR"); 199dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lib_dir) 200dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "using deprecated IPTABLES_LIB_DIR \n"); 201dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 202dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lib_dir == NULL) 203dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lib_dir = XT_LIB_DIR; 204dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 205dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 206dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 207dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int parse_ipt(struct action_util *a,int *argc_p, 208dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char ***argv_p, int tca_id, struct nlmsghdr *n) 209dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 210dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct xtables_target *m = NULL; 211dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ipt_entry fw; 212dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tail; 213dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int c; 214dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int rargc = *argc_p; 215dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char **argv = *argv_p; 216dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int argc = 0, iargc = 0; 217dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char k[16]; 218dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int res = -1; 219dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int size = 0; 220dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int iok = 0, ok = 0; 221dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 hook = 0, index = 0; 222dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = 0; 223dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 224dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat set_lib_dir(); 225dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 226dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 227dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 228dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i = 0; i < rargc; i++) { 229dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL == argv[i] || 0 == strcmp(argv[i], "action")) { 230dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 231dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 232dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 233dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iargc = argc = i; 234dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 235dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 236dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc <= 2) { 237dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr,"bad arguements to ipt %d vs %d \n", argc, rargc); 238dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 239dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 240dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 241dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (1) { 242dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat c = getopt_long(argc, argv, "j:", opts, NULL); 243dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (c == -1) 244dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 245dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat switch (c) { 246dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat case 'j': 247dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m = find_target(optarg, TRY_LOAD); 248dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL != m) { 249dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 250dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (0 > build_st(m, NULL)) { 251dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf(" %s error \n", m->name); 252dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 253dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 254dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat opts = 255dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat merge_options(opts, m->extra_opts, 256dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat &m->option_offset); 257dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 258dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr," failed to find target %s\n\n", optarg); 259dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 260dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 261dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ok++; 262dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 263dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 264dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat default: 265dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&fw, 0, sizeof (fw)); 266dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (m) { 267dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->parse(c - m->option_offset, argv, 0, 268dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat &m->tflags, NULL, &m->t); 269dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 270dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr," failed to find target %s\n\n", optarg); 271dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 272dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 273dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 274dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ok++; 275dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 276dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 277dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 278dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 279dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 280dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (iargc > optind) { 281dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(argv[optind], "index") == 0) { 282dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&index, argv[optind + 1], 10)) { 283dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"index\"\n"); 284dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free_opts(opts); 285dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 286dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 287dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iok++; 288dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 289dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat optind += 2; 290dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 291dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 292dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 293dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ok && !iok) { 294dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr," ipt Parser BAD!! (%s)\n", *argv); 295dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 296dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 297dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 298dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* check that we passed the correct parameters to the target */ 299dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (m) 300dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->final_check(m->tflags); 301dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 302dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 303dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tcmsg *t = NLMSG_DATA(n); 304dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (t->tcm_parent != TC_H_ROOT 305dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat && t->tcm_parent == TC_H_MAJ(TC_H_INGRESS)) { 306dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat hook = NF_IP_PRE_ROUTING; 307dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 308dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat hook = NF_IP_POST_ROUTING; 309dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 310dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 311dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 312dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail = NLMSG_TAIL(n); 313dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, tca_id, NULL, 0); 314dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stdout, "tablename: %s hook: %s\n ", tname, ipthooks[hook]); 315dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stdout, "\ttarget: "); 316dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 317dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (m) 318dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->print(NULL, m->t, 0); 319dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stdout, " index %d\n", index); 320dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 321dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strlen(tname) > 16) { 322dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat size = 16; 323dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat k[15] = 0; 324dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 325dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat size = 1 + strlen(tname); 326dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 327dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strncpy(k, tname, size); 328dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 329dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, TCA_IPT_TABLE, k, size); 330dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, TCA_IPT_HOOK, &hook, 4); 331dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, TCA_IPT_INDEX, &index, 4); 332dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (m) 333dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, TCA_IPT_TARG, m->t, m->t->u.target_size); 334dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 335dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 336dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc -= optind; 337dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argv += optind; 338dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argc_p = rargc - iargc; 339dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argv_p = argv; 340dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 341dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat optind = 0; 342dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free_opts(opts); 343dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* Clear flags if target will be used again */ 344dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->tflags=0; 345dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->used=0; 346dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* Free allocated memory */ 347dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (m->t) 348dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free(m->t); 349dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 350dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 351dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 352dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 353dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 354dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 355dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int 356dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatprint_ipt(struct action_util *au,FILE * f, struct rtattr *arg) 357dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 358dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tb[TCA_IPT_MAX + 1]; 359dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct xt_entry_target *t = NULL; 360dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 361dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (arg == NULL) 362dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 363dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 364dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat set_lib_dir(); 365dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 366dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(tb, TCA_IPT_MAX, arg); 367dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 368dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_TABLE] == NULL) { 369dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "[NULL ipt table name ] assuming mangle "); 370dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 371dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "tablename: %s ", 372dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (char *) RTA_DATA(tb[TCA_IPT_TABLE])); 373dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 374dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 375dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_HOOK] == NULL) { 376dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "[NULL ipt hook name ]\n "); 377dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 378dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 379dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 hook; 380dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat hook = *(__u32 *) RTA_DATA(tb[TCA_IPT_HOOK]); 381dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " hook: %s \n", ipthooks[hook]); 382dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 383dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 384dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_TARG] == NULL) { 385dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\t[NULL ipt target parameters ] \n"); 386dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 387dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 388dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct xtables_target *m = NULL; 389dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t = RTA_DATA(tb[TCA_IPT_TARG]); 390dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m = find_target(t->u.user.name, TRY_LOAD); 391dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL != m) { 392dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (0 > build_st(m, t)) { 393dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " %s error \n", m->name); 394dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 395dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 396dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 397dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat opts = 398dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat merge_options(opts, m->extra_opts, 399dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat &m->option_offset); 400dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 401dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " failed to find target %s\n\n", 402dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t->u.user.name); 403dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 404dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 405dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\ttarget "); 406dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m->print(NULL, m->t, 0); 407dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_INDEX] == NULL) { 408dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " [NULL ipt target index ]\n"); 409dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 410dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 index; 411dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat index = *(__u32 *) RTA_DATA(tb[TCA_IPT_INDEX]); 412dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " \n\tindex %d", index); 413dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 414dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 415dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_CNT]) { 416dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cnt *c = RTA_DATA(tb[TCA_IPT_CNT]);; 417dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " ref %d bind %d", c->refcnt, c->bindcnt); 418dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 419dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats) { 420dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_IPT_TM]) { 421dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tcf_t *tm = RTA_DATA(tb[TCA_IPT_TM]); 422dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_tm(f,tm); 423dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 424dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 425dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " \n"); 426dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 427dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 428dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free_opts(opts); 429dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 430dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 431dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 432dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 433dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct action_util ipt_action_util = { 434dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .id = "ipt", 435dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .parse_aopt = parse_ipt, 436dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .print_aopt = print_ipt, 437dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 438dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 439