1/* Shared library add-on to iptables to add simple load-balance support. */ 2#include <stdio.h> 3#include <netdb.h> 4#include <string.h> 5#include <stdlib.h> 6#include <getopt.h> 7#include <iptables.h> 8#include <linux/netfilter_ipv4/ip_tables.h> 9#include <linux/netfilter_ipv4/ip_nat_rule.h> 10 11#define BREAKUP_IP(x) (x)>>24, ((x)>>16) & 0xFF, ((x)>>8) & 0xFF, (x) & 0xFF 12 13/* Function which prints out usage message. */ 14static void 15help(void) 16{ 17 printf( 18"BALANCE v%s options:\n" 19" --to-destination <ipaddr>-<ipaddr>\n" 20" Addresses to map destination to.\n", 21IPTABLES_VERSION); 22} 23 24static struct option opts[] = { 25 { "to-destination", 1, 0, '1' }, 26 { 0 } 27}; 28 29/* Initialize the target. */ 30static void 31init(struct ipt_entry_target *t, unsigned int *nfcache) 32{ 33 struct ip_nat_multi_range *mr = (struct ip_nat_multi_range *)t->data; 34 35 /* Actually, it's 0, but it's ignored at the moment. */ 36 mr->rangesize = 1; 37 38 /* Can't cache this */ 39 *nfcache |= NFC_UNKNOWN; 40} 41 42/* Parses range of IPs */ 43static void 44parse_to(char *arg, struct ip_nat_range *range) 45{ 46 char *dash; 47 struct in_addr *ip; 48 49 range->flags |= IP_NAT_RANGE_MAP_IPS; 50 dash = strchr(arg, '-'); 51 if (dash) 52 *dash = '\0'; 53 else 54 exit_error(PARAMETER_PROBLEM, "Bad IP range `%s'\n", arg); 55 56 ip = dotted_to_addr(arg); 57 if (!ip) 58 exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n", 59 arg); 60 range->min_ip = ip->s_addr; 61 ip = dotted_to_addr(dash+1); 62 if (!ip) 63 exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n", 64 dash+1); 65 range->max_ip = ip->s_addr; 66} 67 68/* Function which parses command options; returns true if it 69 ate an option */ 70static int 71parse(int c, char **argv, int invert, unsigned int *flags, 72 const struct ipt_entry *entry, 73 struct ipt_entry_target **target) 74{ 75 struct ip_nat_multi_range *mr 76 = (struct ip_nat_multi_range *)(*target)->data; 77 78 switch (c) { 79 case '1': 80 if (check_inverse(optarg, &invert, NULL, 0)) 81 exit_error(PARAMETER_PROBLEM, 82 "Unexpected `!' after --to-destination"); 83 84 parse_to(optarg, &mr->range[0]); 85 *flags = 1; 86 return 1; 87 88 default: 89 return 0; 90 } 91} 92 93/* Final check; need --to-dest. */ 94static void final_check(unsigned int flags) 95{ 96 if (!flags) 97 exit_error(PARAMETER_PROBLEM, 98 "BALANCE needs --to-destination"); 99} 100 101/* Prints out the targinfo. */ 102static void 103print(const struct ipt_ip *ip, 104 const struct ipt_entry_target *target, 105 int numeric) 106{ 107 struct ip_nat_multi_range *mr 108 = (struct ip_nat_multi_range *)target->data; 109 struct ip_nat_range *r = &mr->range[0]; 110 struct in_addr a; 111 112 a.s_addr = r->min_ip; 113 114 printf("balance %s", addr_to_dotted(&a)); 115 a.s_addr = r->max_ip; 116 printf("-%s ", addr_to_dotted(&a)); 117} 118 119/* Saves the union ipt_targinfo in parsable form to stdout. */ 120static void 121save(const struct ipt_ip *ip, const struct ipt_entry_target *target) 122{ 123 struct ip_nat_multi_range *mr 124 = (struct ip_nat_multi_range *)target->data; 125 struct ip_nat_range *r = &mr->range[0]; 126 struct in_addr a; 127 128 a.s_addr = r->min_ip; 129 printf("--to-destination %s", addr_to_dotted(&a)); 130 a.s_addr = r->max_ip; 131 printf("-%s ", addr_to_dotted(&a)); 132} 133 134static 135struct iptables_target balance 136= { NULL, 137 "BALANCE", 138 IPTABLES_VERSION, 139 IPT_ALIGN(sizeof(struct ip_nat_multi_range)), 140 IPT_ALIGN(sizeof(struct ip_nat_multi_range)), 141 &help, 142 &init, 143 &parse, 144 &final_check, 145 &print, 146 &save, 147 opts 148}; 149 150void _init(void) 151{ 152 register_target(&balance); 153} 154