int do_nat(struct params *params) { int c,optindex; struct iptargs *ipt = malloc(sizeof(struct iptargs)); struct argstruct *args = get_args(params); struct ipt_natinfo *target; memset(ipt,0,sizeof(struct iptargs)); ipt->table = "nat"; ipt->chain = NULL; optind = 1; while ((c = getopt_long(args->argc, args->argv, "A:L::s:d:j:o:i:S:D:F:",global_options,&optindex)) != -1) { printf("#CC:%d %c#\n", c, c); switch(c) { case 'A': ipt->chain = strdup(optarg); printf("chain=%s\n",ipt->chain); ipt->op = APPEND; break; case 'L': if (optarg) { ipt->chain = strdup(optarg); } ipt->op = LIST; break; case 's': ipt->flags|=SRC_F; parse_ip(ipt, 's', optarg); break; case 'd': ipt->flags|=DST_F; parse_ip(ipt, 'd', optarg); break; case 'j': if (!optarg) { printf("Must specify target\n"); return 1; } ipt->target = strdup(optarg); if ((optarg)&&(strcmp(optarg,"SNAT")==0||strcmp(optarg,"DNAT")==0)) { size_t size; size = IPT_ALIGN(sizeof(struct nat_nf_nat_multi_range)) + sizeof(struct nat_xt_entry_target); target = malloc(size); memset(target,0,size); target->t.target_size = size; if ( strlen(optarg)<XT_FUNCTION_MAXNAMELEN) memcpy(target->t.name,optarg,strlen(optarg)); } break; case 'o': ipt->flags|=IPT_INV_VIA_OUT; if (ipt_parse_interface(optarg,ipt->out_if,ipt->out_if_mask)) return 1; break; case 'i': ipt->flags|=IPT_INV_VIA_IN; if (ipt_parse_interface(optarg,ipt->out_if,ipt->out_if_mask)) return 1; break; case 'S' : if(!NAT_target_parse(c,optarg,&target)) printf("SNAT_target_parse error\n"); break; case 'Z' : if(!NAT_target_parse(c,optarg,&target)) printf("DNAT_target_parse error\n"); break; case 'D': ipt->chain = optarg; ipt->rulenum = strtoul(args->argv[optind++], NULL, 10); ipt->op = DELETE; break; case 'F': if (optarg) { ipt->chain = optarg; } ipt->op = FLUSH; break; default: printf("not recognized\n"); break; } } if (check_ipt_command(ipt)) return 1; switch (ipt->op) { case APPEND: do_append_nat_entry(ipt,target); break; case LIST: do_list_entries(ipt); break; case DELETE: do_delete_entry(ipt); break; case FLUSH: do_flush_entries(ipt); break; default: break; } return 0; }
/** * Run the given select statement and call 'proc' on the resulting * values (which must be in particular positions). * * @param plugin the plugin handle * @param stmt select statement to run * @param proc function to call on result * @param proc_cls closure for proc * @param ... arguments to initialize stmt */ static void execute_select (struct Plugin *plugin, struct GNUNET_MYSQL_StatementHandle *stmt, PluginDatumProcessor proc, void *proc_cls, ...) { va_list ap; int ret; unsigned int type; unsigned int priority; unsigned int anonymity; unsigned long long exp; unsigned long hashSize; unsigned long size; unsigned long long uid; char value[GNUNET_DATASTORE_MAX_VALUE_SIZE]; struct GNUNET_HashCode key; struct GNUNET_TIME_Absolute expiration; MYSQL_BIND rbind[7]; hashSize = sizeof (struct GNUNET_HashCode); memset (rbind, 0, sizeof (rbind)); rbind[0].buffer_type = MYSQL_TYPE_LONG; rbind[0].buffer = &type; rbind[0].is_unsigned = 1; rbind[1].buffer_type = MYSQL_TYPE_LONG; rbind[1].buffer = &priority; rbind[1].is_unsigned = 1; rbind[2].buffer_type = MYSQL_TYPE_LONG; rbind[2].buffer = &anonymity; rbind[2].is_unsigned = 1; rbind[3].buffer_type = MYSQL_TYPE_LONGLONG; rbind[3].buffer = &exp; rbind[3].is_unsigned = 1; rbind[4].buffer_type = MYSQL_TYPE_BLOB; rbind[4].buffer = &key; rbind[4].buffer_length = hashSize; rbind[4].length = &hashSize; rbind[5].buffer_type = MYSQL_TYPE_BLOB; rbind[5].buffer = value; rbind[5].buffer_length = size = sizeof (value); rbind[5].length = &size; rbind[6].buffer_type = MYSQL_TYPE_LONGLONG; rbind[6].buffer = &uid; rbind[6].is_unsigned = 1; va_start (ap, proc_cls); ret = GNUNET_MYSQL_statement_run_prepared_select_va (plugin->mc, stmt, 7, rbind, NULL, NULL, ap); va_end (ap); if (ret <= 0) { proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } GNUNET_assert (size <= sizeof (value)); if ((rbind[4].buffer_length != sizeof (struct GNUNET_HashCode)) || (hashSize != sizeof (struct GNUNET_HashCode))) { GNUNET_break (0); proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } expiration.abs_value_us = exp; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u-byte value under key `%s' with prio %u, anon %u, expire %s selecting from gn090 table\n", (unsigned int) size, GNUNET_h2s (&key), priority, anonymity, GNUNET_STRINGS_absolute_time_to_string (expiration)); GNUNET_assert (size < MAX_DATUM_SIZE); ret = proc (proc_cls, &key, size, value, type, priority, anonymity, expiration, uid); if (ret == GNUNET_NO) { do_delete_entry (plugin, uid); if (size != 0) plugin->env->duc (plugin->env->cls, -size); } }