I have found an old script written in C and when I try to compile it I get the following message
# gcc libipt_rope.c -o libipt_rope.solibipt_rope.c:349: error: variable ‘rope’ has initializer but incomplete typelibipt_rope.c:350: error: unknown field ‘next’ specified in initializerlibipt_rope.c:350: warning: excess elements in struct initializerlibipt_rope.c:350: warning: (near initialization for ‘rope’)libipt_rope.c:351: error: unknown field ‘name’ specified in initializerlibipt_rope.c:351: warning: excess elements in struct initializerlibipt_rope.c:351: warning: (near initialization for ‘rope’)libipt_rope.c:352: error: unknown field ‘version’ specified in initializerlibipt_rope.c:352: warning: excess elements in struct initializerlibipt_rope.c:352: warning: (near initialization for ‘rope’)libipt_rope.c:353: error: unknown field ‘size’ specified in initializerlibipt_rope.c:353: warning: excess elements in struct initializerlibipt_rope.c:353: warning: (near initialization for ‘rope’)libipt_rope.c:354: error: unknown field ‘userspacesize’ specified in initializerlibipt_rope.c:354: warning: excess elements in struct initializerlibipt_rope.c:354: warning: (near initialization for ‘rope’)libipt_rope.c:355: error: unknown field ‘help’ specified in initializerlibipt_rope.c:355: warning: excess elements in struct initializerlibipt_rope.c:355: warning: (near initialization for ‘rope’)libipt_rope.c:356: error: unknown field ‘init’ specified in initializerlibipt_rope.c:356: warning: excess elements in struct initializerlibipt_rope.c:356: warning: (near initialization for ‘rope’)libipt_rope.c:357: error: unknown field ‘parse’ specified in initializerlibipt_rope.c:357: warning: excess elements in struct initializerlibipt_rope.c:357: warning: (near initialization for ‘rope’)libipt_rope.c:358: error: unknown field ‘final_check’ specified in initializerlibipt_rope.c:358: warning: excess elements in struct initializerlibipt_rope.c:358: warning: (near initialization for ‘rope’)libipt_rope.c:359: error: unknown field ‘print’ specified in initializerlibipt_rope.c:359: warning: excess elements in struct initializerlibipt_rope.c:359: warning: (near initialization for ‘rope’)libipt_rope.c:360: error: unknown field ‘save’ specified in initializerlibipt_rope.c:360: warning: excess elements in struct initializerlibipt_rope.c:360: warning: (near initialization for ‘rope’)libipt_rope.c:361: error: unknown field ‘extra_opts’ specified in initializerlibipt_rope.c:362: warning: excess elements in struct initializerlibipt_rope.c:362: warning: (near initialization for ‘rope’
I'm asking the C gurus, since i'm quite familiar with C, but not that much.
And here's the code
/
/* For detailed documentation about ROPE, visit http://www.lowth.com/rope */#include <sys/socket.h>#include <sys/types.h>#include <sys/stat.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <netdb.h>#include <string.h>#include <stdlib.h>#include <getopt.h>#include <ctype.h>#include <fcntl.h>#include <unistd.h>#include <assert.h>#include "iptables.h"#define _USERLAND_ 1#define _ROPE_IPTABLES_ 1#include "rope.h"#include "rope-enum.h"#define WANT_ROPE_LOAD_SCRIPT#include "rope-util.h"#define IPT_ROPE_SCRIPT 0x0001#define IPT_ROPE_PUSH_INT 0x0002#define IPT_ROPE_PUSH_STR 0x0004#define IPT_ROPE_PUSH_IP 0x0008#define OPT_SCRIPT "rope-script"#define OPT_PUSH_INT "rope-push-int"#define OPT_PUSH_STR "rope-push-str"#define OPT_PUSH_IP "rope-push-ip"/* Function which prints out usage message. */static void help(void){ printf("ROPE (version " ROPE_VERSION ") match v%s options:\n""[!] --" OPT_SCRIPT " scriptfile Name of packet-matching ROPE script\n"" --" OPT_PUSH_INT " integer Push integer onto stack\n"" --" OPT_PUSH_STR " string Push string onto stack\n"" --" OPT_PUSH_IP " ip-address Push IPv4 address onto stack\n",IPTABLES_VERSION); fputc('\n', stdout);}static struct option opts[] = { { "script", 1, 0, '1' }, // for backwards compatibility { OPT_SCRIPT, 1, 0, '1' }, { OPT_PUSH_INT, 1, 0, '2' }, { OPT_PUSH_STR, 1, 0, '3' }, { OPT_PUSH_IP, 1, 0, '4' }, {0}};/* Initialize the match. */static void init(struct ipt_entry_match *m, unsigned int *nfcache){ struct ipt_rope_info *ropeinfo = (struct ipt_rope_info *)(m)->data; *nfcache |= NFC_UNKNOWN; memset(ropeinfo, 0, sizeof(*ropeinfo)); ropeinfo->version = ROPE_SCRIPT_VERSION; ropeinfo->info_size = (u_int16_t)sizeof(struct ipt_rope_info);}static void read_scriptfile(struct ipt_rope_info *info, char *filename){ int i; int len = strlen(filename); char *scriptdir = "/etc/rope.d/scripts"; char path[ROPE_MAX_FILENAME + strlen(scriptdir)+8]; struct stat stat_info; int ok, script_offset, script_len, ipsets_offset, ipsets_len, used_buff; if (len < 1) exit_error(PARAMETER_PROBLEM, "Script file name cannot be empty" ); if (len >= ROPE_MAX_FILENAME) exit_error(PARAMETER_PROBLEM, "Script file name too long" ); for (i=0; i<len; i++) { char c = filename[i]; if ( !isalnum(c) && c != '-'&& c != '_' ) exit_error( PARAMETER_PROBLEM,"Script file name can only contain letters, digits or hyphens" ); } strcpy(path, scriptdir); strcat(path, "/"); strcat(path, filename); strcat(path, ".rp"); /* Verify that it is safe to load scripts from the directory */ if (lstat(scriptdir, &stat_info) != 0) exit_error( PARAMETER_PROBLEM, "Cant stat '%s'", scriptdir ); if (!S_ISDIR(stat_info.st_mode)) exit_error( PARAMETER_PROBLEM, "'%s' is not a directory (it should be)", scriptdir); if (stat_info.st_uid != 0) exit_error( PARAMETER_PROBLEM, "Directory '%s' is not owned by 'root' (it should be)", scriptdir); if (stat_info.st_mode & (S_IWGRP | S_IWOTH)) exit_error( PARAMETER_PROBLEM, "Directory '%s' may be writeable by non-root users (it should not be)", scriptdir); /* Verify that only root can modify it */ if (lstat(path, &stat_info) != 0) exit_error( PARAMETER_PROBLEM, "Cant stat '%s'", path); if (!S_ISREG(stat_info.st_mode)) exit_error( PARAMETER_PROBLEM, "'%s' is not a regular file (it should be)", path); if (stat_info.st_uid != 0) exit_error( PARAMETER_PROBLEM, "File '%s' is not owned by 'root' (it should be)", path); if (stat_info.st_mode & (S_IWGRP | S_IWOTH)) exit_error( PARAMETER_PROBLEM, "File '%s' may be writeable by non-root users (it should not be)", path); strcpy(info->scriptfile, filename); ok = rope_load_script( path, info->scriptbuff+info->arguments_len, ROPE_MAX_COMPILED_SIZE - info->arguments_len, &used_buff,&script_offset, &script_len,&ipsets_offset, &ipsets_len ); if ( !ok ) exit_error( PARAMETER_PROBLEM, "Cant load file '%s'", path ); info->script_offset = 0; info->script_len = info->arguments_len + script_len; info->ipsets_offset = ipsets_offset + info->arguments_len; info->ipsets_len = ipsets_len; info->scriptbuff_len = used_buff;}/* 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, unsigned int *nfcache, struct ipt_entry_match **match){ struct ipt_rope_info *ropeinfo = (struct ipt_rope_info *)(*match)->data; int n, len, i; struct hostent *he; char push_buff[ROPE_MAX_COMPILED_SIZE]; int push_len = 0; switch (c) { case '1': // --rope-script ropeinfo->invert = invert; if (*flags & IPT_ROPE_SCRIPT) exit_error( PARAMETER_PROBLEM, "--"OPT_SCRIPT": cant specify more than one script"); read_scriptfile( ropeinfo, optarg ); *flags |= IPT_ROPE_SCRIPT; break; case '2': // --rope-push-int if (invert) exit_error( PARAMETER_PROBLEM, "--"OPT_PUSH_INT": cant specify '!'"); n = atoi(optarg); if (n >= 0 && n <= 127) { push_buff[push_len++] = ROPE_ELEMENT_TYPE_INTEGER8; push_buff[push_len++] = n; } else if (n >= 0 && n <= 32767) { push_buff[push_len++] = ROPE_ELEMENT_TYPE_INTEGER16; push_buff[push_len++] = ((unsigned int)n & 0xff00) >> 8; push_buff[push_len++] = ((unsigned int)n & 0x00ff); } else { push_buff[push_len++] = ROPE_ELEMENT_TYPE_INTEGER; push_buff[push_len++] = ((unsigned int)n & 0xff000000) >> 24; push_buff[push_len++] = ((unsigned int)n & 0x00ff0000) >> 16; push_buff[push_len++] = ((unsigned int)n & 0x0000ff00) >> 8; push_buff[push_len++] = ((unsigned int)n & 0x000000ff); } *flags |= IPT_ROPE_PUSH_INT; break; case '3': // --rope-push-str if (invert) exit_error( PARAMETER_PROBLEM, "--"OPT_PUSH_STR": cant specify '!'"); len = strlen(optarg); if ((len + 3) > sizeof(push_buff)) exit_error( PARAMETER_PROBLEM, "--"OPT_PUSH_STR": string too long" ); if (len < 128) { push_buff[push_len++] = ROPE_ELEMENT_TYPE_STRING8; push_buff[push_len++] = len; } else { push_buff[push_len++] = ROPE_ELEMENT_TYPE_STRING; push_buff[push_len++] = (len & 0xff00) >> 8; push_buff[push_len++] = (len & 0x00ff); } /* * We have to check that the string we provide will work with iptables-save and * iptables-restore - which are rather crude in their parsing of the config * file they use. Non printable characters, control characters and quotes will * all cause us problems. */ for (i=0; i<len; i++) { if (iscntrl(optarg[i]) || !isprint(optarg[i])) exit_error( PARAMETER_PROBLEM, "--"OPT_PUSH_STR": string includes non-printable character(s)"); if (optarg[i] == '"') exit_error( PARAMETER_PROBLEM, "--"OPT_PUSH_STR": string includes double-quote character(s)"); } memcpy(push_buff+push_len, optarg, len); push_len += len; *flags |= IPT_ROPE_PUSH_STR; break; case '4': // --rope-push-ip if (invert) exit_error( PARAMETER_PROBLEM, "--"OPT_PUSH_IP": cant specify '!'"); he = gethostbyname( optarg ); if (he == NULL) exit_error( PARAMETER_PROBLEM, "--"OPT_PUSH_IP": cant resolve host name"); if (he->h_length != 4) exit_error( PARAMETER_PROBLEM, "--"OPT_PUSH_IP": IPv4 address expected"); if ( he->h_addr_list == NULL || he->h_addr_list[0] == NULL || he->h_addr_list[1] != NULL) exit_error( PARAMETER_PROBLEM, "--"OPT_PUSH_IP": name resolved to multiple IPv4 addresses"); push_buff[push_len++] = ROPE_ELEMENT_TYPE_DOTTED_STRING8; push_buff[push_len++] = 4; memcpy(push_buff + push_len, he->h_addr_list[0], 4); push_len += 4; *flags |= IPT_ROPE_PUSH_IP; break; default: return 0; } memmove( ropeinfo->scriptbuff + ropeinfo->arguments_len + push_len, ropeinfo->scriptbuff + ropeinfo->arguments_len, ropeinfo->scriptbuff_len - ropeinfo->arguments_len ); memcpy(ropeinfo->scriptbuff + ropeinfo->arguments_len, push_buff, push_len); ropeinfo->script_len += push_len; ropeinfo->ipsets_offset += push_len; ropeinfo->arguments_len += push_len; ropeinfo->scriptbuff_len += push_len; return 1;}/* Final check; must have specified --string. */static void final_check(unsigned int flags){ if (! (flags & IPT_ROPE_SCRIPT) ) exit_error( PARAMETER_PROBLEM,"ROPE match: You must specify `--" OPT_SCRIPT "'" );}static void print_string(int len, unsigned char *str){ putchar( '\"' ); while (len) { putchar(*str); /*if (ch == '\n') printf( "\\n" ); else if (ch == '\r') printf( "\\r" ); else if (ch == '\t') printf( "\\t" ); else if (ch == '"') printf( "\\\"" ); else if (ch == '\\') printf( "\\\\" ); else if (isprint( ch )) printf( "%c", ch ); else printf( "\\%03o", ch );*/ str ++; len --; } putchar( '\"' );}static void print_pushes(struct ipt_rope_info *info, char *prefix, char *delim){ int opcode, len; unsigned char *buff = info->scriptbuff; unsigned char *end = info->scriptbuff + info->arguments_len; while (buff < end) { opcode = (*buff++); if (opcode == ROPE_ELEMENT_TYPE_INTEGER8) { printf( "%spush-int%s%d", prefix, delim, (*buff++) ); } else if (opcode == ROPE_ELEMENT_TYPE_INTEGER16) { printf( "%spush-int%s%d", prefix, delim, buff[0] << 8 | buff[1]); buff += 2; } else if (opcode == ROPE_ELEMENT_TYPE_INTEGER) { printf( "%spush-int%s%d", prefix, delim, buff[0] << 24 | buff[1] << 16 | buff[2] << 8 | buff[3]); buff += 4; } else if (opcode == ROPE_ELEMENT_TYPE_DOTTED_STRING8 && *buff == 4) { printf( "%spush-ip%s%d.%d.%d.%d", prefix, delim, buff[1], buff[2], buff[3], buff[4] ); buff += 5; } else if (opcode == ROPE_ELEMENT_TYPE_STRING8) { len = buff[0]; printf( "%spush-str%s", prefix, delim ); print_string(len, buff+1); buff += len + 1; } else if (opcode == ROPE_ELEMENT_TYPE_STRING) { len = buff[0] << 8 | buff[1]; printf( "%spush-str%s", prefix, delim ); print_string(len, buff+2); buff += len + 2; } else { return; } printf( "" ); }}/* Prints out the matchinfo. */static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric){ printf( "ROPE script: %s%s ", ((struct ipt_rope_info *)match->data)->invert ? "!" : "", ((struct ipt_rope_info *)match->data)->scriptfile ); print_pushes((struct ipt_rope_info *)match->data, "", ":");}/* Saves the union ipt_matchinfo in parsable form to stdout. */static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match){ printf( "%s--" OPT_SCRIPT " %s ", ((struct ipt_rope_info *)match->data)->invert ? "! " : "", ((struct ipt_rope_info *)match->data)->scriptfile ); print_pushes((struct ipt_rope_info *)match->data, "--rope-", "");}static struct iptables_match rope = { .next = NULL, .name = "rope", .version = IPTABLES_VERSION, .size = IPT_ALIGN(sizeof(struct ipt_rope_info)), .userspacesize = IPT_ALIGN(sizeof(struct ipt_rope_info)), .help = &help, .init = &init, .parse = &parse, .final_check = &final_check, .print = &print, .save = &save, .extra_opts = opts};void _init(void){ register_match(&rope);}
Thanks for reading :)