Пожалуйста, коллега:/*
* This one handles all table-related commands
* ipfw table N add addr[/masklen] [value]
* ipfw table N delete addr[/masklen]
* ipfw table N flush
* ipfw table N list
*/
static void
table_handler(int ac, char *av[])
{
ipfw_table_entry ent;
ipfw_table *tbl;
int do_add;
char *p;
socklen_t l;
uint32_t a;
ac--; av++;
if (ac && isdigit(**av)) {
ent.tbl = atoi(*av);
ac--; av++;
} else
errx(EX_USAGE, "table number required");
NEED1("table needs command");
if (strncmp(*av, "add", strlen(*av)) == 0 ||
strncmp(*av, "delete", strlen(*av)) == 0) {
do_add = **av == 'a';
ac--; av++;
if (!ac)
errx(EX_USAGE, "IP address required");
p = strchr(*av, '/');
if (p) {
*p++ = '\0';
ent.masklen = atoi(p);
if (ent.masklen > 32)
errx(EX_DATAERR, "bad width ``%s''", p);
} else
ent.masklen = 32;
if (lookup_host(*av, (struct in_addr *)&ent.addr) != 0)
errx(EX_NOHOST, "hostname ``%s'' unknown", *av);
ac--; av++;
if (do_add && ac)
ent.value = strtoul(*av, NULL, 0);
else
ent.value = 0;
if (do_cmd(do_add ? IP_FW_TABLE_ADD : IP_FW_TABLE_DEL,
&ent, sizeof(ent)) < 0)
err(EX_OSERR, "setsockopt(IP_FW_TABLE_%s)",
do_add ? "ADD" : "DEL");
} else if (strncmp(*av, "flush", strlen(*av)) == 0) {
if (do_cmd(IP_FW_TABLE_FLUSH, &ent.tbl, sizeof(ent.tbl)) < 0)
err(EX_OSERR, "setsockopt(IP_FW_TABLE_FLUSH)");
} else if (strncmp(*av, "list", strlen(*av)) == 0) {
a = ent.tbl;
l = sizeof(a);
if (do_cmd(IP_FW_TABLE_GETSIZE, &a, (uintptr_t)&l) < 0)
err(EX_OSERR, "getsockopt(IP_FW_TABLE_GETSIZE)");
l = sizeof(*tbl) + a * sizeof(ipfw_table_entry);
tbl = malloc(l);
if (tbl == NULL)
err(EX_OSERR, "malloc");
tbl->tbl = ent.tbl;
if (do_cmd(IP_FW_TABLE_LIST, tbl, (uintptr_t)&l) < 0)
err(EX_OSERR, "getsockopt(IP_FW_TABLE_LIST)");
for (a = 0; a < tbl->cnt; a++) {
printf("%s/%u %u\n",
inet_ntoa(*(struct in_addr *)&tbl->ent[a].addr),
tbl->ent[a].masklen, tbl->ent[a].value);
}
} else
errx(EX_USAGE, "invalid table command %s", *av);
}