int get_pinhole_info(unsigned short uid, char * rem_host, int rem_hostlen, unsigned short * rem_port, char * int_client, int int_clientlen, unsigned short * int_port, int * proto, unsigned int * timestamp, u_int64_t * packets, u_int64_t * bytes) { struct pinhole_t * p; p = get_pinhole(uid); if(!p) return -2; /* Not found */ if(rem_host) { if(inet_ntop(AF_INET6, &p->saddr, rem_host, rem_hostlen) == NULL) return -1; } if(rem_port) *rem_port = p->sport; if(int_client) { if(inet_ntop(AF_INET6, &p->daddr, int_client, int_clientlen) == NULL) return -1; } if(int_port) *int_port = p->dport; if(proto) *proto = p->proto; if(timestamp) *timestamp = p->timestamp; if(packets || bytes) { /* theses informations need to be read from netfilter */ IP6TC_HANDLE h; const struct ip6t_entry * e; const struct ip6t_entry_match * match; h = ip6tc_init("filter"); if(!h) { syslog(LOG_ERR, "ip6tc_init error : %s", ip6tc_strerror(errno)); return -1; } for(e = ip6tc_first_rule(miniupnpd_v6_filter_chain, h); e; e = ip6tc_next_rule(e, h)) { if((e->ipv6.proto == p->proto) && (0 == memcmp(&e->ipv6.src, &p->saddr, sizeof(e->ipv6.src))) && (0 == memcmp(&e->ipv6.dst, &p->daddr, sizeof(e->ipv6.dst)))) { const struct ip6t_tcp * info; match = (const struct ip6t_entry_match *)&e->elems; info = (const struct ip6t_tcp *)&match->data; if((info->spts[0] == p->sport) && (info->dpts[0] == p->dport)) { if(packets) *packets = e->counters.pcnt; if(bytes) *bytes = e->counters.bcnt; break; } } } ip6tc_free(h); } return 0; }
int main(int argc, char *argv[]) #endif { int ret; char *table = "filter"; struct ip6tc_handle *handle = NULL; ip6tables_globals.program_name = "ip6tables"; #if !defined(ALL_INCLUSIVE) && !defined(NO_SHARED_LIBS) ret = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6); if (ret < 0) { fprintf(stderr, "%s/%s Failed to initialize xtables\n", ip6tables_globals.program_name, ip6tables_globals.program_version); exit(1); } #endif #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) init_extensions(); #endif ret = do_command6(argc, argv, &table, &handle); if (ret) { ret = ip6tc_commit(handle); ip6tc_free(handle); } if (!ret) { if (errno == EINVAL) { fprintf(stderr, "ip6tables: %s. " "Run `dmesg' for more information.\n", ip6tc_strerror(errno)); } else { fprintf(stderr, "[%s %d]ip6tables: %s.\n", __FILE__,__LINE__,ip6tc_strerror(errno)); } } exit(!ret); }
static int do_iptables(int argc, char* argv[]) { char *table = "filter"; int ret = 0; if(!find_table(argc, argv)) return 0; #ifdef IP6T ret = do_command6(argc, argv, &table, ¤t_table->handle, true); if (!ret) { fprintf(stderr, "line %d: %s\n", current_line, ip6tc_strerror(errno)); } else { if(!table || strcmp(table, current_table->name)) { fprintf(stderr, "line %d: expected table %s, got %s\n", current_line, current_table->name, table); exit(1); } } #else ret = do_command4(argc, argv, &table, ¤t_table->handle, true); if (!ret) { fprintf(stderr, "line %d: %s\n", current_line, iptc_strerror(errno)); } else { if(!table || strcmp(table, current_table->name)) { fprintf(stderr, "line %d: expected table %s, got %s\n", current_line, current_table->name, table); exit(1); } } #endif return ret; }
int ip6tables_close ( struct ip6tc_handle* handle, int updated ) { int res = 1; int sav_errno ; if (updated) { if ( ( res = ip6tc_commit ( handle ) ) != 1 ) { sav_errno = errno ; log_message(LOG_INFO, "iptc_commit returned %d: %s", res, ip6tc_strerror (sav_errno) ); } } ip6tc_free ( handle ) ; if ( res == 1 ) return 0 ; else return ( sav_errno ) ; }
int main(int argc, char *argv[]) { int ret; char *table = "filter"; ip6tc_handle_t handle = NULL; program_name = "ip6tables"; program_version = IPTABLES_VERSION; #ifdef NO_SHARED_LIBS init_extensions(); #endif ret = do_command6(argc, argv, &table, &handle); if (ret) ret = ip6tc_commit(&handle); if (!ret) fprintf(stderr, "ip6tables: %s\n", ip6tc_strerror(errno)); exit(!ret); }
int main(int argc, char *argv[]) #endif { struct ip6tc_handle *handle = NULL; char buffer[10240]; int c; char curtable[IP6T_TABLE_MAXNAMELEN + 1]; FILE *in; int in_table = 0, testing = 0; line = 0; ip6tables_globals.program_name = "ip6tables-restore"; c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6); if (c < 0) { fprintf(stderr, "%s/%s Failed to initialize xtables\n", ip6tables_globals.program_name, ip6tables_globals.program_version); exit(1); } #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) init_extensions(); init_extensions6(); #endif while ((c = getopt_long(argc, argv, "bcvthnM:", options, NULL)) != -1) { switch (c) { case 'b': binary = 1; break; case 'c': counters = 1; break; case 'v': verbose = 1; break; case 't': testing = 1; break; case 'h': print_usage("ip6tables-restore", IPTABLES_VERSION); break; case 'n': noflush = 1; break; case 'M': xtables_modprobe_program = optarg; break; } } if (optind == argc - 1) { in = fopen(argv[optind], "re"); if (!in) { fprintf(stderr, "Can't open %s: %s\n", argv[optind], strerror(errno)); exit(1); } } else if (optind < argc) { fprintf(stderr, "Unknown arguments found on commandline\n"); exit(1); } else in = stdin; /* Grab standard input. */ while (fgets(buffer, sizeof(buffer), in)) { int ret = 0; line++; if (buffer[0] == '\n') continue; else if (buffer[0] == '#') { if (verbose) fputs(buffer, stdout); continue; } else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) { if (!testing) { DEBUGP("Calling commit\n"); ret = ip6tc_commit(handle); ip6tc_free(handle); handle = NULL; } else { DEBUGP("Not calling commit, testing\n"); ret = 1; } in_table = 0; } else if ((buffer[0] == '*') && (!in_table)) { /* New table */ char *table; table = strtok(buffer+1, " \t\n"); DEBUGP("line %u, table '%s'\n", line, table); if (!table) { xtables_error(PARAMETER_PROBLEM, "%s: line %u table name invalid\n", ip6tables_globals.program_name, line); exit(1); } strncpy(curtable, table, IP6T_TABLE_MAXNAMELEN); curtable[IP6T_TABLE_MAXNAMELEN] = '\0'; if (handle) ip6tc_free(handle); handle = create_handle(table); if (noflush == 0) { DEBUGP("Cleaning all chains of table '%s'\n", table); for_each_chain6(flush_entries6, verbose, 1, handle); DEBUGP("Deleting all user-defined chains " "of table '%s'\n", table); for_each_chain6(delete_chain6, verbose, 0, handle); } ret = 1; in_table = 1; } else if ((buffer[0] == ':') && (in_table)) { /* New chain. */ char *policy, *chain; chain = strtok(buffer+1, " \t\n"); DEBUGP("line %u, chain '%s'\n", line, chain); if (!chain) { xtables_error(PARAMETER_PROBLEM, "%s: line %u chain name invalid\n", ip6tables_globals.program_name, line); exit(1); } if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN) xtables_error(PARAMETER_PROBLEM, "Invalid chain name `%s' " "(%u chars max)", chain, XT_EXTENSION_MAXNAMELEN - 1); if (ip6tc_builtin(chain, handle) <= 0) { if (noflush && ip6tc_is_chain(chain, handle)) { DEBUGP("Flushing existing user defined chain '%s'\n", chain); if (!ip6tc_flush_entries(chain, handle)) xtables_error(PARAMETER_PROBLEM, "error flushing chain " "'%s':%s\n", chain, strerror(errno)); } else { DEBUGP("Creating new chain '%s'\n", chain); if (!ip6tc_create_chain(chain, handle)) xtables_error(PARAMETER_PROBLEM, "error creating chain " "'%s':%s\n", chain, strerror(errno)); } } policy = strtok(NULL, " \t\n"); DEBUGP("line %u, policy '%s'\n", line, policy); if (!policy) { xtables_error(PARAMETER_PROBLEM, "%s: line %u policy invalid\n", ip6tables_globals.program_name, line); exit(1); } if (strcmp(policy, "-") != 0) { struct ip6t_counters count; if (counters) { char *ctrs; ctrs = strtok(NULL, " \t\n"); if (!ctrs || !parse_counters(ctrs, &count)) xtables_error(PARAMETER_PROBLEM, "invalid policy counters " "for chain '%s'\n", chain); } else { memset(&count, 0, sizeof(struct ip6t_counters)); } DEBUGP("Setting policy of chain %s to %s\n", chain, policy); if (!ip6tc_set_policy(chain, policy, &count, handle)) xtables_error(OTHER_PROBLEM, "Can't set policy `%s'" " on `%s' line %u: %s\n", policy, chain, line, ip6tc_strerror(errno)); } ret = 1; } else if (in_table) { int a; char *ptr = buffer; char *pcnt = NULL; char *bcnt = NULL; char *parsestart; /* the parser */ char *curchar; int quote_open, escaped; size_t param_len; /* reset the newargv */ newargc = 0; if (buffer[0] == '[') { /* we have counters in our input */ ptr = strchr(buffer, ']'); if (!ptr) xtables_error(PARAMETER_PROBLEM, "Bad line %u: need ]\n", line); pcnt = strtok(buffer+1, ":"); if (!pcnt) xtables_error(PARAMETER_PROBLEM, "Bad line %u: need :\n", line); bcnt = strtok(NULL, "]"); if (!bcnt) xtables_error(PARAMETER_PROBLEM, "Bad line %u: need ]\n", line); /* start command parsing after counter */ parsestart = ptr + 1; } else { /* start command parsing at start of line */ parsestart = buffer; } add_argv(argv[0]); add_argv("-t"); add_argv(curtable); if (counters && pcnt && bcnt) { add_argv("--set-counters"); add_argv((char *) pcnt); add_argv((char *) bcnt); } /* After fighting with strtok enough, here's now * a 'real' parser. According to Rusty I'm now no * longer a real hacker, but I can live with that */ quote_open = 0; escaped = 0; param_len = 0; for (curchar = parsestart; *curchar; curchar++) { char param_buffer[1024]; if (quote_open) { if (escaped) { param_buffer[param_len++] = *curchar; escaped = 0; continue; } else if (*curchar == '\\') { escaped = 1; continue; } else if (*curchar == '"') { quote_open = 0; *curchar = ' '; } else { param_buffer[param_len++] = *curchar; continue; } } else { if (*curchar == '"') { quote_open = 1; continue; } } if (*curchar == ' ' || *curchar == '\t' || * curchar == '\n') { if (!param_len) { /* two spaces? */ continue; } param_buffer[param_len] = '\0'; /* check if table name specified */ if (!strncmp(param_buffer, "-t", 2) || !strncmp(param_buffer, "--table", 8)) { xtables_error(PARAMETER_PROBLEM, "Line %u seems to have a " "-t table option.\n", line); exit(1); } add_argv(param_buffer); param_len = 0; } else { /* regular character, copy to buffer */ param_buffer[param_len++] = *curchar; if (param_len >= sizeof(param_buffer)) xtables_error(PARAMETER_PROBLEM, "Parameter too long!"); } } DEBUGP("calling do_command6(%u, argv, &%s, handle):\n", newargc, curtable); for (a = 0; a < newargc; a++) DEBUGP("argv[%u]: %s\n", a, newargv[a]); ret = do_command6(newargc, newargv, &newargv[2], &handle); free_argv(); fflush(stdout); } if (!ret) { fprintf(stderr, "%s: line %u failed\n", ip6tables_globals.program_name, line); exit(1); } } if (in_table) { fprintf(stderr, "%s: COMMIT expected at line %u\n", ip6tables_globals.program_name, line + 1); exit(1); } if (in != NULL) fclose(in); return 0; }
static int do_output(const char *tablename) { ip6tc_handle_t h; const char *chain = NULL; if (!tablename) return for_each_table(&do_output); h = ip6tc_init(tablename); if (!h) exit_error(OTHER_PROBLEM, "Can't initialize: %s\n", ip6tc_strerror(errno)); if (!binary) { time_t now = time(NULL); printf("# Generated by ip6tables-save v%s on %s", IPTABLES_VERSION, ctime(&now)); printf("*%s\n", tablename); /* Dump out chain names first, * thereby preventing dependency conflicts */ for (chain = ip6tc_first_chain(&h); chain; chain = ip6tc_next_chain(&h)) { printf(":%s ", chain); if (ip6tc_builtin(chain, h)) { struct ip6t_counters count; printf("%s ", ip6tc_get_policy(chain, &count, &h)); printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt); } else { printf("- [0:0]\n"); } } for (chain = ip6tc_first_chain(&h); chain; chain = ip6tc_next_chain(&h)) { const struct ip6t_entry *e; /* Dump out rules */ e = ip6tc_first_rule(chain, &h); while(e) { print_rule(e, &h, chain, counters); e = ip6tc_next_rule(e, &h); } } now = time(NULL); printf("COMMIT\n"); printf("# Completed on %s", ctime(&now)); } else { /* Binary, huh? OK. */ exit_error(OTHER_PROBLEM, "Binary NYI\n"); } ip6tc_free(&h); return 1; }
int main(int argc, char *argv[]) { ip6tc_handle_t handle; char buffer[10240]; unsigned int line = 0; int c; char curtable[IP6T_TABLE_MAXNAMELEN + 1]; FILE *in; const char *modprobe = 0; program_name = "ip6tables-restore"; program_version = IPTABLES_VERSION; #ifdef NO_SHARED_LIBS init_extensions(); #endif while ((c = getopt_long(argc, argv, "bcvhnM:", options, NULL)) != -1) { switch (c) { case 'b': binary = 1; break; case 'c': counters = 1; break; case 'v': verbose = 1; break; case 'h': print_usage("ip6tables-restore", IPTABLES_VERSION); break; case 'n': noflush = 1; break; case 'M': modprobe = optarg; break; } } if (optind == argc - 1) { in = fopen(argv[optind], "r"); if (!in) { fprintf(stderr, "Can't open %s: %s", argv[optind], strerror(errno)); exit(1); } } else if (optind < argc) { fprintf(stderr, "Unknown arguments found on commandline"); exit(1); } else in = stdin; /* Grab standard input. */ while (fgets(buffer, sizeof(buffer), in)) { int ret; line++; if (buffer[0] == '\n') continue; else if (buffer[0] == '#') { if (verbose) fputs(buffer, stdout); continue; } else if (strcmp(buffer, "COMMIT\n") == 0) { DEBUGP("Calling commit\n"); ret = ip6tc_commit(&handle); } else if (buffer[0] == '*') { /* New table */ char *table; table = strtok(buffer+1, " \t\n"); DEBUGP("line %u, table '%s'\n", line, table); if (!table) { exit_error(PARAMETER_PROBLEM, "%s: line %u table name invalid\n", program_name, line); exit(1); } strncpy(curtable, table, IP6T_TABLE_MAXNAMELEN); handle = create_handle(table, modprobe); if (noflush == 0) { DEBUGP("Cleaning all chains of table '%s'\n", table); for_each_chain(flush_entries, verbose, 1, &handle); DEBUGP("Deleting all user-defined chains " "of table '%s'\n", table); for_each_chain(delete_chain, verbose, 0, &handle) ; } ret = 1; } else if (buffer[0] == ':') { /* New chain. */ char *policy, *chain; chain = strtok(buffer+1, " \t\n"); DEBUGP("line %u, chain '%s'\n", line, chain); if (!chain) { exit_error(PARAMETER_PROBLEM, "%s: line %u chain name invalid\n", program_name, line); exit(1); } if (!ip6tc_builtin(chain, handle)) { DEBUGP("Creating new chain '%s'\n", chain); if (!ip6tc_create_chain(chain, &handle)) exit_error(PARAMETER_PROBLEM, "error creating chain " "'%s':%s\n", chain, strerror(errno)); } policy = strtok(NULL, " \t\n"); DEBUGP("line %u, policy '%s'\n", line, policy); if (!policy) { exit_error(PARAMETER_PROBLEM, "%s: line %u policy invalid\n", program_name, line); exit(1); } if (strcmp(policy, "-") != 0) { struct ip6t_counters count; if (counters) { char *ctrs; ctrs = strtok(NULL, " \t\n"); parse_counters(ctrs, &count); } else { memset(&count, 0, sizeof(struct ip6t_counters)); } DEBUGP("Setting policy of chain %s to %s\n", chain, policy); if (!ip6tc_set_policy(chain, policy, &count, &handle)) exit_error(OTHER_PROBLEM, "Can't set policy `%s'" " on `%s' line %u: %s\n", chain, policy, line, ip6tc_strerror(errno)); } ret = 1; } else { int a; char *ptr = buffer; char *pcnt = NULL; char *bcnt = NULL; char *parsestart; /* the parser */ char *param_start, *curchar; int quote_open; /* reset the newargv */ newargc = 0; if (buffer[0] == '[') { /* we have counters in our input */ ptr = strchr(buffer, ']'); if (!ptr) exit_error(PARAMETER_PROBLEM, "Bad line %u: need ]\n", line); pcnt = strtok(buffer+1, ":"); if (!pcnt) exit_error(PARAMETER_PROBLEM, "Bad line %u: need :\n", line); bcnt = strtok(NULL, "]"); if (!bcnt) exit_error(PARAMETER_PROBLEM, "Bad line %u: need ]\n", line); /* start command parsing after counter */ parsestart = ptr + 1; } else { /* start command parsing at start of line */ parsestart = buffer; } add_argv(argv[0]); add_argv("-t"); add_argv((char *) &curtable); if (counters && pcnt && bcnt) { add_argv("--set-counters"); add_argv((char *) pcnt); add_argv((char *) bcnt); } /* After fighting with strtok enough, here's now * a 'real' parser. According to Rusty I'm now no * longer a real hacker, but I can live with that */ quote_open = 0; param_start = parsestart; for (curchar = parsestart; *curchar; curchar++) { if (*curchar == '"') { if (quote_open) { quote_open = 0; *curchar = ' '; } else { quote_open = 1; param_start++; } } if (*curchar == ' ' || *curchar == '\t' || * curchar == '\n') { char param_buffer[1024]; int param_len = curchar-param_start; if (quote_open) continue; if (!param_len) { /* two spaces? */ param_start++; continue; } /* end of one parameter */ strncpy(param_buffer, param_start, param_len); *(param_buffer+param_len) = '\0'; /* check if table name specified */ if (!strncmp(param_buffer, "-t", 3) || !strncmp(param_buffer, "--table", 8)) { exit_error(PARAMETER_PROBLEM, "Line %u seems to have a " "-t table option.\n", line); exit(1); } add_argv(param_buffer); param_start += param_len + 1; } else { /* regular character, skip */ } } DEBUGP("calling do_command6(%u, argv, &%s, handle):\n", newargc, curtable); for (a = 0; a < newargc; a++) DEBUGP("argv[%u]: %s\n", a, newargv[a]); ret = do_command6(newargc, newargv, &newargv[2], &handle); free_argv(); } if (!ret) { fprintf(stderr, "%s: line %u failed\n", program_name, line); exit(1); } } return 0; }
int ip6tables_add_rules(struct ip6tc_handle* handle, const char* chain_name, int rulenum, int dim, int src_dst, const char* target_name, const char* set_name, uint16_t protocol, int param, int cmd, bool ignore_errors) { size_t size; struct ip6t_entry *fw; struct xt_entry_target *target; struct xt_entry_match *match; #ifdef HAVE_XT_SET_INFO_MATCH_V1 struct xt_set_info_match_v1 *setinfo; #else struct xt_set_info_match *setinfo; #endif ip6t_chainlabel chain; int res; int sav_errno; /* Add an entry */ memset(chain, 0, sizeof(chain)); size = XT_ALIGN(sizeof (struct ip6t_entry)) + XT_ALIGN(sizeof(struct xt_entry_match)) + XT_ALIGN(sizeof(struct xt_entry_target) + 1) + XT_ALIGN(sizeof(*setinfo)); if (protocol == IPPROTO_ICMPV6) size += XT_ALIGN(sizeof(struct xt_entry_match)) + XT_ALIGN(sizeof(struct ip6t_icmp)); fw = (struct ip6t_entry*)MALLOC(size); fw->target_offset = XT_ALIGN(sizeof(struct ip6t_entry)); // set match = (struct xt_entry_match*)((char*)fw + fw->target_offset); match->u.match_size = XT_ALIGN(sizeof(struct xt_entry_match)) + XT_ALIGN(sizeof(*setinfo)); #ifdef HAVE_XT_SET_INFO_MATCH_V1 match->u.user.revision = 1; #else match->u.user.revision = 0; #endif fw->target_offset += match->u.match_size; strcpy(match->u.user.name, "set"); #ifdef HAVE_XT_SET_INFO_MATCH_V1 setinfo = (struct xt_set_info_match_v1 *)match->data; #else setinfo = (struct xt_set_info_match *)match->data; #endif get_set_byname (set_name, &setinfo->match_set, NFPROTO_IPV6, ignore_errors); if (setinfo->match_set.index == IPSET_INVALID_ID) { FREE(fw); return -1; } setinfo->match_set.dim = dim; setinfo->match_set.flags = src_dst; if (protocol != IPPROTO_NONE) { fw->ipv6.proto = protocol; fw->ipv6.flags |= IP6T_F_PROTO ; // IPv6 only if (protocol == IPPROTO_ICMPV6) { match = (struct xt_entry_match*)((char*)fw + fw->target_offset); match->u.match_size = XT_ALIGN(sizeof(struct xt_entry_match)) + XT_ALIGN(sizeof(struct ip6t_icmp)); match->u.user.revision = 0; fw->target_offset += match->u.match_size; strcpy(match->u.user.name, "icmp6"); struct ip6t_icmp *icmpinfo = (struct ip6t_icmp *)match->data; icmpinfo->type = param; // type to match icmpinfo->code[0] = 0; // code lower icmpinfo->code[1] = 0xff; // code upper icmpinfo->invflags = 0; // don't invert } } // target is XTC_LABEL_DROP/XTC_LABEL_ACCEPT fw->next_offset = size; target = ip6t_get_target(fw); target->u.user.target_size = XT_ALIGN(sizeof(struct xt_entry_target) + 1); strcpy(target->u.user.name, target_name); // fw->ip.flags |= IP6T_F_GOTO; strcpy(chain, chain_name); // Use iptc_append_entry to add to the chain if (cmd == IPADDRESS_DEL) { unsigned char matchmask[fw->next_offset]; memset(matchmask, 0xff, fw->next_offset); res = ip6tc_delete_entry(chain, fw, matchmask, handle); } else if (rulenum == -1) res = ip6tc_append_entry(chain, fw, handle) ; else res = ip6tc_insert_entry(chain, fw, rulenum, handle) ; sav_errno = errno; FREE(fw); if (res!= 1) { if (!ignore_errors) log_message(LOG_INFO, "ip6tc_insert_entry for chain %s returned %d: %s", chain, res, ip6tc_strerror(sav_errno)) ; return sav_errno; } return 0; }
int ip6tables_process_entry( struct ip6tc_handle* handle, const char* chain_name, int rulenum, const char* target_name, const ip_address_t* src_ip_address, const ip_address_t* dst_ip_address, const char* in_iface, const char* out_iface, uint16_t protocol, uint16_t type, int cmd, bool force) { size_t size; struct ip6t_entry *fw; struct xt_entry_target *target; struct xt_entry_match *match ; ip6t_chainlabel chain; int res; int sav_errno; /* Add an entry */ memset (chain, 0, sizeof (chain)); size = XT_ALIGN (sizeof (struct ip6t_entry)) + XT_ALIGN (sizeof (struct xt_entry_target) + 1); if ( protocol == IPPROTO_ICMPV6 ) size += XT_ALIGN ( sizeof(struct xt_entry_match) ) + XT_ALIGN ( sizeof(struct ip6t_icmp) ) ; fw = (struct ip6t_entry*)MALLOC(size); fw->target_offset = XT_ALIGN ( sizeof ( struct ip6t_entry ) ) ; if ( src_ip_address && src_ip_address->ifa.ifa_family != AF_UNSPEC ) { memcpy(&fw->ipv6.src, &src_ip_address->u.sin6_addr, sizeof ( src_ip_address->u.sin6_addr ) ); memset ( &fw->ipv6.smsk, 0xff, sizeof(fw->ipv6.smsk)); } if ( dst_ip_address && dst_ip_address->ifa.ifa_family != AF_UNSPEC ) { memcpy(&fw->ipv6.dst, &dst_ip_address->u.sin6_addr, sizeof ( dst_ip_address->u.sin6_addr ) ); memset ( &fw->ipv6.dmsk, 0xff, sizeof(fw->ipv6.smsk)); } if (in_iface) set_iface(fw->ipv6.iniface, fw->ipv6.iniface_mask, in_iface); if (out_iface) set_iface(fw->ipv6.outiface, fw->ipv6.outiface_mask, out_iface); if ( protocol != IPPROTO_NONE ) { fw->ipv6.proto = protocol ; fw->ipv6.flags |= IP6T_F_PROTO ; // IPv6 only if ( protocol == IPPROTO_ICMPV6 ) { match = (struct xt_entry_match*)((char*)fw + fw->target_offset); match->u.match_size = XT_ALIGN ( sizeof (struct xt_entry_match) ) + XT_ALIGN ( sizeof (struct ip6t_icmp) ) ; match->u.user.revision = 0; fw->target_offset += match->u.match_size ; strcpy ( match->u.user.name, "icmp6" ) ; struct ip6t_icmp *icmpinfo = (struct ip6t_icmp *) match->data; icmpinfo->type = type ; // type to match icmpinfo->code[0] = 0 ; // code lower icmpinfo->code[1] = 0xff ; // code upper icmpinfo->invflags = 0 ; // don't invert } } // target is XTC_LABEL_DROP/XTC_LABEL_ACCEPT fw->next_offset = size; target = ip6t_get_target ( fw ) ; target->u.user.target_size = XT_ALIGN (sizeof (struct xt_entry_target) + 1); strcpy (target->u.user.name, target_name ); // fw->ip.flags |= IPT_F_GOTO; strcpy (chain, chain_name); // Use iptc_append_entry to add to the chain if (cmd == IPADDRESS_DEL) { unsigned char matchmask[fw->next_offset]; memset(matchmask, 0xff, fw->next_offset); res = ip6tc_delete_entry ( chain, fw, matchmask, handle); } else if ( rulenum == -1 ) res = ip6tc_append_entry (chain, fw, handle ) ; else res = ip6tc_insert_entry (chain, fw, rulenum, handle ) ; sav_errno = errno ; if (res != 1 && (!force || sav_errno != ENOENT)) { log_message(LOG_INFO, "ip6tables_process_entry for chain %s returned %d: %s", chain, res, ip6tc_strerror (sav_errno) ) ; return sav_errno ; } return 0 ; }