From patchwork Sun Dec 9 19:54:14 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 204778 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id BA8742C0131 for ; Mon, 10 Dec 2012 06:54:25 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934472Ab2LITyX (ORCPT ); Sun, 9 Dec 2012 14:54:23 -0500 Received: from mail-we0-f202.google.com ([74.125.82.202]:40646 "EHLO mail-we0-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934440Ab2LITyW (ORCPT ); Sun, 9 Dec 2012 14:54:22 -0500 Received: by mail-we0-f202.google.com with SMTP id t57so130580wey.1 for ; Sun, 09 Dec 2012 11:54:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer; bh=RsN1LpeKM2mJl2T1MS8kjRars5v8ceur8GSgIV3u6tY=; b=YB8reiyKx06rZBhc1SsZUqsMPEa3HR9BqwI22ohHqWv1PwhXCcqshlc3NY09s5NiDI +VCBXenc3BSG8lYZYvxMOXmzHD9jCTjFafzvOOw883eq6FHVGApLixq6kXm6AsDJMDnz 1rxBkaLp1n+/GTF3RYiJrrQA7fAxaN26Njlf+Nfptt5rbzn8l98PmLoMVpDfmgWN6MTw FxtnS+Jr8E08WcN12SMpyZA6YxYo5zdeAcqhPcWynxLvWBoOX4hnLSieYJJRP93SPNGw fm0nDG8Vm0N+nCR2AC79Buv2nqFfx3DUA2lLltFKLfw0CoMVmfgnf18sGHiQXiswbtyy 44aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:x-gm-message-state; bh=RsN1LpeKM2mJl2T1MS8kjRars5v8ceur8GSgIV3u6tY=; b=ilqxaoWS69Xw9unaxvkNU1GNWD0NUEcSBvzgFEj7dvdE8EjmHMR8zlcdrRF84plHql uJZ4GlD+3IgjThFOrb1DsIxN6/xc0abXVLERH+7MMvor2yiADjbX5qtFeeDyLkw+R/50 DBv3n8C0QvaozkRQbvQsml4tbGrinOIz6oBBtSb14hoi/8qWOn7R3I6WiKyHh1fwRyYY l1/0UQ1+4PaCrsH/DnJJ/CbS4Bzgj00++QHXfMR2Dx1phQkSjlupycVKAcfdhDkNh34k be9anMZCRGIbBfFnNEanwVfr+RslwY8hPJ7ZffbznX+tCJkJ0MB4P0M/l/C75nzAJbzn OScA== Received: by 10.14.201.1 with SMTP id a1mr9289270eeo.3.1355082860311; Sun, 09 Dec 2012 11:54:20 -0800 (PST) Received: from hpza10.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id z44si7504965een.0.2012.12.09.11.54.20 (version=TLSv1/SSLv3 cipher=AES128-SHA); Sun, 09 Dec 2012 11:54:20 -0800 (PST) Received: from gopher.nyc.corp.google.com (gopher.nyc.corp.google.com [172.26.106.37]) by hpza10.eem.corp.google.com (Postfix) with ESMTP id E003820004E; Sun, 9 Dec 2012 11:54:19 -0800 (PST) Received: by gopher.nyc.corp.google.com (Postfix, from userid 29878) id 5F23D1E06F7; Sun, 9 Dec 2012 14:54:19 -0500 (EST) From: Willem de Bruijn To: netfilter-devel@vger.kernel.org, pablo@netfilter.org Cc: Willem de Bruijn Subject: [PATCH next] extensions: add libxt_skbuff extension Date: Sun, 9 Dec 2012 14:54:14 -0500 Message-Id: <1355082854-31853-1-git-send-email-willemb@google.com> X-Mailer: git-send-email 1.7.7.3 X-Gm-Message-State: ALoCoQlvxcPFg1umcJXVD0cONth3A6FQP2NtbotqgYkTT4qxEdE/YhUas95QATMNRej15N/Urg+yAJGFVJK4e1UMKNeuOHXEoCA8KLlr3wy6lxfBBccqsCZsKyZe1qhkkwu7/W19Yp5QvYDsLkkZgF2ASR/rKd+pWgmB4WrbiTIN31O1l/3czRRV/o+PI81wwpeVIY5i3jrX5MVdAO0fH5i8ffYa/gjSjg== Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Support filtering based on sk_buff fields --- extensions/libxt_skbuff.c | 157 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 157 insertions(+), 0 deletions(-) create mode 100644 extensions/libxt_skbuff.c diff --git a/extensions/libxt_skbuff.c b/extensions/libxt_skbuff.c new file mode 100644 index 0000000..02dba82 --- /dev/null +++ b/extensions/libxt_skbuff.c @@ -0,0 +1,157 @@ +/* + * Xtables skb match extension + * + * Written by Willem de Bruijn (willemb@google.com) + * Copyright Google, Inc. 2012 + * Licensed under the GNU General Public License version 2 (GPLv2) +*/ + +#include +#include +#include +#include +#include + +enum { O_FIELD = 0, + O_VAL_EXACT, + O_VAL_MIN, + O_VAL_MAX, + O_VAL_MASK}; + +const char *skbuff_field_names[] = { + "csum", "hatype", "iif", "len", "mark", "pkt_type", "priority", + "protocol", "queue_mapping", "rt_classid", "rxhash", "secmark", + "uid", "gid", "tstamp", "vlan_tci"}; + +static void skbuff_help(void) +{ + int i, len; + + printf( +"skbuff match options:\n" +"[!] --field --val [--mask ]\n" +"[!] --field --min --max [--mask ]\n" +"where name is one of "); + + len = sizeof(skbuff_field_names) / sizeof (void *); + for (i = 0; i < len; i++) + printf("%s ", skbuff_field_names[i]); + printf("\n"); +} + +static const struct xt_option_entry skbuff_opts[] = { + {.name = "field", .id = O_FIELD, .type = XTTYPE_STRING, + .flags = XTOPT_MAND | XTOPT_INVERT}, + {.name = "val", .id = O_VAL_EXACT, .type = XTTYPE_UINT64}, + {.name = "min", .id = O_VAL_MIN, .type = XTTYPE_UINT64}, + {.name = "max", .id = O_VAL_MAX, .type = XTTYPE_UINT64}, + {.name = "mask", .id = O_VAL_MASK, .type = XTTYPE_UINT64}, + XTOPT_TABLEEND, +}; + +static int skbuff_field_name_to_id(const char *name) +{ + int i, len = sizeof(skbuff_field_names) / sizeof (void *); + + for (i = 0; i < len; i++) + if (!strcmp(skbuff_field_names[i], name)) + return i; + + xtables_error(PARAMETER_PROBLEM, "skbuff: unknown field\n"); +} + +static void skbuff_parse(struct xt_option_call *cb) +{ + struct xt_skbuff_info *info = cb->data; + + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_FIELD: + info->field_id = skbuff_field_name_to_id(cb->arg); + if (cb->invert) + info->invert = 1; + break; + case O_VAL_EXACT: + info->min = info->max = strtoul(cb->arg, NULL, 0); + break; + case O_VAL_MIN: + info->min = strtoul(cb->arg, NULL, 0); + break; + case O_VAL_MAX: + info->max = strtoul(cb->arg, NULL, 0); + break; + case O_VAL_MASK: + info->mask = strtoul(cb->arg, NULL, 0); + break; + default: + xtables_error(PARAMETER_PROBLEM, + "skbuff: unknown argument"); + break; + } +} + +static void skbuff_check(struct xt_fcheck_call *cb) +{ + struct xt_skbuff_info *info = cb->data; + unsigned int val_mask, ran_mask, opt_mask; + + if (!info->mask) + info->mask = (uint64_t) -1; + + val_mask = 1 << O_VAL_EXACT; + ran_mask = (1 << O_VAL_MIN) | (1 << O_VAL_MAX); + opt_mask = val_mask | ran_mask; + + if (((cb->xflags & opt_mask) != val_mask) && + ((cb->xflags & opt_mask) != ran_mask)) + xtables_error(PARAMETER_PROBLEM, + "skbuff: specify one of --val or --min/--max"); +} + +static void skbuff_save(const void *ip, const struct xt_entry_match *match) +{ + const struct xt_skbuff_info *info = (void *) match->data; + + printf("%s--field %s --min %llu --max %llu --mask 0x%llx", + info->invert ? "! " : "", skbuff_field_names[info->field_id], + (unsigned long long) info->min, + (unsigned long long) info->max, + (unsigned long long) info->mask); +} + +static void skbuff_print(const void *ip, const struct xt_entry_match *match, + int numeric) +{ + const struct xt_skbuff_info *info = (void *) match->data; + + printf(" skbuff match "); + if (numeric) + printf("%hu", info->field_id); + else + printf("%s", skbuff_field_names[info->field_id]); + + printf("%llu %llu %llx %u", + (unsigned long long) info->min, + (unsigned long long) info->max, + (unsigned long long) info->mask, + info->invert); +} + +static struct xtables_match skbuff_match = { + .family = NFPROTO_UNSPEC, + .name = "skbuff", + .version = XTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_skbuff_info)), + .help = skbuff_help, + .print = skbuff_print, + .save = skbuff_save, + .x6_parse = skbuff_parse, + .x6_fcheck = skbuff_check, + .x6_options = skbuff_opts, +}; + +void _init(void) +{ + xtables_register_match(&skbuff_match); +} +