Files
xtables-addons/extensions/libxt_ipp2p.c
2011-02-02 05:09:58 +01:00

248 lines
7.4 KiB
C

/*
* "ipp2p" match extension for iptables
* Eicke Friedrich/Klaus Degner <ipp2p@ipp2p.org>, 2005 - 2006
* Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2009
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License; either
* version 2 of the License, or any later version, as published by the
* Free Software Foundation.
*/
#include <stdbool.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <ctype.h>
#include <xtables.h>
#include "xt_ipp2p.h"
#include "compat_user.h"
#define param_act(t, s, f) xtables_param_act((t), "ipp2p", (s), (f))
static void ipp2p_mt_help(void)
{
printf(
"ipp2p v%s match options:\n"
" --edk [tcp,udp] All known eDonkey/eMule/Overnet packets\n"
" --dc [tcp] All known Direct Connect packets\n"
" --kazaa [tcp,udp] All known KaZaA packets\n"
" --gnu [tcp,udp] All known Gnutella packets\n"
" --bit [tcp,udp] All known BitTorrent packets\n"
" --apple [tcp] All known AppleJuice packets\n"
" --winmx [tcp] All known WinMX\n"
" --soul [tcp] All known SoulSeek\n"
" --ares [tcp] All known Ares\n\n"
"EXPERIMENTAL protocols:\n"
" --mute [tcp] All known Mute packets\n"
" --waste [tcp] All known Waste packets\n"
" --xdcc [tcp] All known XDCC packets (only xdcc login)\n\n"
, IPP2P_VERSION);
}
static const struct option ipp2p_mt_opts[] = {
{.name = "edk", .has_arg = false, .val = '2'},
{.name = "dc", .has_arg = false, .val = '7'},
{.name = "gnu", .has_arg = false, .val = '9'},
{.name = "kazaa", .has_arg = false, .val = 'a'},
{.name = "bit", .has_arg = false, .val = 'b'},
{.name = "apple", .has_arg = false, .val = 'c'},
{.name = "soul", .has_arg = false, .val = 'd'},
{.name = "winmx", .has_arg = false, .val = 'e'},
{.name = "ares", .has_arg = false, .val = 'f'},
{.name = "mute", .has_arg = false, .val = 'g'},
{.name = "waste", .has_arg = false, .val = 'h'},
{.name = "xdcc", .has_arg = false, .val = 'i'},
{.name = "debug", .has_arg = false, .val = 'j'},
{NULL},
};
static int ipp2p_mt_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
{
struct ipt_p2p_info *info = (struct ipt_p2p_info *)(*match)->data;
switch (c) {
case '2': /*cmd: edk*/
param_act(XTF_ONLY_ONCE, "--edk", *flags & IPP2P_EDK);
param_act(XTF_NO_INVERT, "--edk", invert);
if (*flags & IPP2P_DATA_EDK)
xtables_error(PARAMETER_PROBLEM,
"ipp2p: use `--edk' OR `--edk-data' but not both of them!");
*flags |= IPP2P_EDK;
info->cmd |= IPP2P_EDK;
break;
case '7': /*cmd: dc*/
param_act(XTF_ONLY_ONCE, "--dc", *flags & IPP2P_DC);
param_act(XTF_NO_INVERT, "--dc", invert);
if (*flags & IPP2P_DATA_DC)
xtables_error(PARAMETER_PROBLEM,
"ipp2p: use `--dc' OR `--dc-data' but not both of them!");
*flags |= IPP2P_DC;
info->cmd |= IPP2P_DC;
break;
case '9': /*cmd: gnu*/
param_act(XTF_ONLY_ONCE, "--gnu", *flags & IPP2P_GNU);
param_act(XTF_NO_INVERT, "--gnu", invert);
if (*flags & IPP2P_DATA_GNU)
xtables_error(PARAMETER_PROBLEM,
"ipp2p: use `--gnu' OR `--gnu-data' but not both of them!");
*flags |= IPP2P_GNU;
info->cmd |= IPP2P_GNU;
break;
case 'a': /*cmd: kazaa*/
param_act(XTF_ONLY_ONCE, "--kazaa", *flags & IPP2P_KAZAA);
param_act(XTF_NO_INVERT, "--kazaa", invert);
if (*flags & IPP2P_DATA_KAZAA)
xtables_error(PARAMETER_PROBLEM,
"ipp2p: use `--kazaa' OR `--kazaa-data' but not both of them!");
*flags |= IPP2P_KAZAA;
info->cmd |= IPP2P_KAZAA;
break;
case 'b': /*cmd: bit*/
param_act(XTF_ONLY_ONCE, "--bit", *flags & IPP2P_BIT);
param_act(XTF_NO_INVERT, "--bit", invert);
*flags |= IPP2P_BIT;
info->cmd |= IPP2P_BIT;
break;
case 'c': /*cmd: apple*/
param_act(XTF_ONLY_ONCE, "--apple", *flags & IPP2P_APPLE);
param_act(XTF_NO_INVERT, "--apple", invert);
*flags |= IPP2P_APPLE;
info->cmd |= IPP2P_APPLE;
break;
case 'd': /*cmd: soul*/
param_act(XTF_ONLY_ONCE, "--soul", *flags & IPP2P_SOUL);
param_act(XTF_NO_INVERT, "--soul", invert);
*flags |= IPP2P_SOUL;
info->cmd |= IPP2P_SOUL;
break;
case 'e': /*cmd: winmx*/
param_act(XTF_ONLY_ONCE, "--winmx", *flags & IPP2P_WINMX);
param_act(XTF_NO_INVERT, "--winmx", invert);
*flags |= IPP2P_WINMX;
info->cmd |= IPP2P_WINMX;
break;
case 'f': /*cmd: ares*/
param_act(XTF_ONLY_ONCE, "--ares", *flags & IPP2P_ARES);
param_act(XTF_NO_INVERT, "--ares", invert);
*flags |= IPP2P_ARES;
info->cmd |= IPP2P_ARES;
break;
case 'g': /*cmd: mute*/
param_act(XTF_ONLY_ONCE, "--mute", *flags & IPP2P_MUTE);
param_act(XTF_NO_INVERT, "--mute", invert);
*flags |= IPP2P_MUTE;
info->cmd |= IPP2P_MUTE;
break;
case 'h': /*cmd: waste*/
param_act(XTF_ONLY_ONCE, "--waste", *flags & IPP2P_WASTE);
param_act(XTF_NO_INVERT, "--waste", invert);
*flags |= IPP2P_WASTE;
info->cmd |= IPP2P_WASTE;
break;
case 'i': /*cmd: xdcc*/
param_act(XTF_ONLY_ONCE, "--xdcc", *flags & IPP2P_XDCC);
param_act(XTF_NO_INVERT, "--xdcc", invert);
*flags |= IPP2P_XDCC;
info->cmd |= IPP2P_XDCC;
break;
case 'j': /*cmd: debug*/
param_act(XTF_ONLY_ONCE, "--debug", info->debug);
param_act(XTF_NO_INVERT, "--debug", invert);
info->debug = 1;
break;
default:
// xtables_error(PARAMETER_PROBLEM,
// "\nipp2p-parameter problem: for ipp2p usage type: iptables -m ipp2p --help\n");
return 0;
}
return 1;
}
static void ipp2p_mt_check(unsigned int flags)
{
if (!flags)
xtables_error(PARAMETER_PROBLEM,
"\nipp2p-parameter problem: for ipp2p usage type: iptables -m ipp2p --help\n");
}
static const char *const ipp2p_cmds[] = {
[IPP2N_EDK] = "--edk",
[IPP2N_DATA_KAZAA] = "--kazaa-data",
[IPP2N_DATA_EDK] = "--edk-data",
[IPP2N_DATA_DC] = "--dc-data",
[IPP2N_DC] = "--dc",
[IPP2N_DATA_GNU] = "--gnu-data",
[IPP2N_GNU] = "--gnu",
[IPP2N_KAZAA] = "--kazaa",
[IPP2N_BIT] = "--bit",
[IPP2N_APPLE] = "--apple",
[IPP2N_SOUL] = "--soul",
[IPP2N_WINMX] = "--winmx",
[IPP2N_ARES] = "--ares",
[IPP2N_MUTE] = "--mute",
[IPP2N_WASTE] = "--waste",
[IPP2N_XDCC] = "--xdcc",
};
static void
ipp2p_mt_print1(const void *entry, const struct xt_entry_match *match,
int numeric)
{
const struct ipt_p2p_info *info = (const void *)match->data;
unsigned int i;
for (i = IPP2N_EDK; i <= IPP2N_XDCC; ++i)
if (info->cmd & (1 << i))
printf(" %s ", ipp2p_cmds[i]);
if (info->debug != 0)
printf(" --debug ");
}
static void ipp2p_mt_print(const void *entry,
const struct xt_entry_match *match, int numeric)
{
printf(" ipp2p ");
ipp2p_mt_print1(entry, match, true);
}
static void ipp2p_mt_save(const void *entry, const struct xt_entry_match *match)
{
ipp2p_mt_print1(entry, match, true);
}
static struct xtables_match ipp2p_mt_reg = {
.version = XTABLES_VERSION,
.name = "ipp2p",
.revision = 1,
.family = NFPROTO_IPV4,
.size = XT_ALIGN(sizeof(struct ipt_p2p_info)),
.userspacesize = XT_ALIGN(sizeof(struct ipt_p2p_info)),
.help = ipp2p_mt_help,
.parse = ipp2p_mt_parse,
.final_check = ipp2p_mt_check,
.print = ipp2p_mt_print,
.save = ipp2p_mt_save,
.extra_opts = ipp2p_mt_opts,
};
static __attribute__((constructor)) void ipp2p_mt_ldr(void)
{
xtables_register_match(&ipp2p_mt_reg);
}