/* Shared library add-on to iptables to add DEST target support. */ #include #include #include #include #include #include #include /* Function which prints out usage message. */ static void help(void) { printf( "DEST options:\n" " --to-destination :\n\n" ); } static struct option opts[] = { { "to-destination", 1, 0, '1' }, { 0 } }; /* Initialize the target. */ static void init(struct ipt_entry_target *t, unsigned int *nfcache) { } /* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { char *colon; struct sockaddr_in *sin = (void *) (*target)->data; int port = 65535; printf("%d, %s\n", c, optarg); switch(c) { case '1': colon = strchr(optarg, ':'); if(colon) { port = atoi(colon+1); colon[0] = '\0'; } sin->sin_port = htons(port); inet_aton(optarg, &(sin->sin_addr)); fprintf(stderr, "%x %d\n", sin->sin_addr.s_addr , htons(sin->sin_port)); *flags = 1; break; default: return 0; } return 1; } static void final_check(unsigned int flags) { if (!flags) exit_error(PARAMETER_PROBLEM, "You must specify --to-destination"); } static void print(const struct ipt_ip *ip, const struct ipt_entry_target *target, int numeric) { struct sockaddr_in *sin = (struct sockaddr_in *)target->data; printf("to: %s:%d\n", inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); } /* Saves the union ipt_targinfo in parsable form to stdout. */ static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target) { struct sockaddr_in *sin = (struct sockaddr_in *)target->data; printf("--to-destination %s:%d\n", inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); } static struct iptables_target dest = { .next = NULL, .name = "DEST", .version = IPTABLES_VERSION, .size = IPT_ALIGN(sizeof(struct sockaddr_in)), .userspacesize = IPT_ALIGN(sizeof(struct sockaddr_in)), .help = &help, .init = &init, .parse = &parse, .final_check = &final_check, .print = &print, .save = &save, .extra_opts = opts }; void _init(void) { register_target(&dest); }