1/* Shared library add-on to iptables to add ROUTE target support. 2 * Author : C�dric de Launois, <delaunois@info.ucl.ac.be> 3 */ 4 5#include <stdio.h> 6#include <string.h> 7#include <stdlib.h> 8#include <getopt.h> 9#include <iptables.h> 10#include <net/if.h> 11#include <linux/netfilter_ipv4/ip_tables.h> 12#include <linux/netfilter_ipv4/ipt_ROUTE.h> 13 14/* Function which prints out usage message. */ 15static void 16help(void) 17{ 18 printf( 19"ROUTE target v%s options:\n" 20" --iface name Send this packet directly through iface name.\n" 21" --ifindex index Send this packet directly through iface index.\n" 22"\n", 23IPTABLES_VERSION); 24} 25 26static struct option opts[] = { 27 { "iface", 1, 0, '1' }, 28 { "ifindex", 1, 0, '2' }, 29 { 0 } 30}; 31 32/* Initialize the target. */ 33static void 34init(struct ipt_entry_target *t, unsigned int *nfcache) 35{ 36} 37 38#define IPT_ROUTE_OPT_IF 0x01 39 40/* Function which parses command options; returns true if it 41 ate an option */ 42static int 43parse(int c, char **argv, int invert, unsigned int *flags, 44 const struct ipt_entry *entry, 45 struct ipt_entry_target **target) 46{ 47 struct ipt_route_target_info *route_info = 48 (struct ipt_route_target_info*)(*target)->data; 49 50 switch (c) { 51 char *end; 52 case '1': 53 if (*flags & IPT_ROUTE_OPT_IF) 54 exit_error(PARAMETER_PROBLEM, 55 "Can't specify --iface or --ifindex twice"); 56 57 if (check_inverse(optarg, &invert, NULL, 0)) 58 exit_error(PARAMETER_PROBLEM, 59 "Unexpected `!' after --iface"); 60 61 if (strlen(optarg) > sizeof(route_info->if_name) - 1) 62 exit_error(PARAMETER_PROBLEM, 63 "Maximum interface name length %u", 64 sizeof(route_info->if_name) - 1); 65 66 strcpy(route_info->if_name, optarg); 67 route_info->if_index = 0; 68 *flags |= IPT_ROUTE_OPT_IF; 69 break; 70 71 case '2': 72 if (*flags & IPT_ROUTE_OPT_IF) 73 exit_error(PARAMETER_PROBLEM, 74 "Can't specify --iface or --ifindex twice"); 75 76 if (check_inverse(optarg, &invert, NULL, 0)) 77 exit_error(PARAMETER_PROBLEM, 78 "Unexpected `!' after --ifindex"); 79 80 route_info->if_name[0] = 0; 81 route_info->if_index = strtoul(optarg, &end, 0); 82 if (*end != '\0' || end == optarg) 83 exit_error(PARAMETER_PROBLEM, "Bad ROUTE ifindex `%s'", 84 optarg); 85 86 if (route_info->if_index == 0) 87 exit_error(PARAMETER_PROBLEM, 88 "Interface index can't be 0 !"); 89 90 *flags |= IPT_ROUTE_OPT_IF; 91 break; 92 93 default: 94 return 0; 95 } 96 97 return 1; 98} 99 100static void 101final_check(unsigned int flags) 102{ 103 if (!flags) 104 exit_error(PARAMETER_PROBLEM, 105 "ROUTE target: Parameter --iface is required"); 106} 107 108/* Prints out the targinfo. */ 109static void 110print(const struct ipt_ip *ip, 111 const struct ipt_entry_target *target, 112 int numeric) 113{ 114 const struct ipt_route_target_info *route_info 115 = (const struct ipt_route_target_info *)target->data; 116 117 printf("ROUTE "); 118 119 if (route_info->if_name[0] != 0) 120 printf("iface %s ", route_info->if_name); 121 else 122 printf("ifindex %u ", route_info->if_index); 123} 124 125static 126struct iptables_target route 127= { NULL, 128 "ROUTE", 129 IPTABLES_VERSION, 130 IPT_ALIGN(sizeof(struct ipt_route_target_info)), 131 IPT_ALIGN(sizeof(struct ipt_route_target_info)), 132 &help, 133 &init, 134 &parse, 135 &final_check, 136 &print, 137 NULL, /* save */ 138 opts 139}; 140 141void _init(void) 142{ 143 register_target(&route); 144} 145