Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Shared library add-on to iptables to match |
| 3 | * packets by their type (BROADCAST, UNICAST, MULTICAST). |
| 4 | * |
| 5 | * Michal Ludvig <michal@logix.cz> |
| 6 | */ |
| 7 | #include <stdio.h> |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 8 | #include <string.h> |
Yasuyuki KOZAKAI | 5fd6ec8 | 2007-07-24 07:05:45 +0000 | [diff] [blame] | 9 | #include <xtables.h> |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 10 | #include <linux/if_packet.h> |
Yasuyuki KOZAKAI | 5fd6ec8 | 2007-07-24 07:05:45 +0000 | [diff] [blame] | 11 | #include <linux/netfilter/xt_pkttype.h> |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 12 | |
Jan Engelhardt | de31da3 | 2011-03-02 19:19:16 +0100 | [diff] [blame] | 13 | enum { |
| 14 | O_PKTTYPE = 0, |
| 15 | }; |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 16 | |
| 17 | struct pkttypes { |
| 18 | const char *name; |
| 19 | unsigned char pkttype; |
| 20 | unsigned char printhelp; |
| 21 | const char *help; |
| 22 | }; |
| 23 | |
| 24 | static const struct pkttypes supported_types[] = { |
Harald Welte | ef22543 | 2002-08-07 09:54:45 +0000 | [diff] [blame] | 25 | {"unicast", PACKET_HOST, 1, "to us"}, |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 26 | {"broadcast", PACKET_BROADCAST, 1, "to all"}, |
| 27 | {"multicast", PACKET_MULTICAST, 1, "to group"}, |
| 28 | /* |
| 29 | {"otherhost", PACKET_OTHERHOST, 1, "to someone else"}, |
| 30 | {"outgoing", PACKET_OUTGOING, 1, "outgoing of any type"}, |
| 31 | */ |
| 32 | /* aliases */ |
| 33 | {"bcast", PACKET_BROADCAST, 0, NULL}, |
| 34 | {"mcast", PACKET_MULTICAST, 0, NULL}, |
Harald Welte | ef22543 | 2002-08-07 09:54:45 +0000 | [diff] [blame] | 35 | {"host", PACKET_HOST, 0, NULL} |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 36 | }; |
| 37 | |
Patrick McHardy | 500f483 | 2007-09-08 15:59:04 +0000 | [diff] [blame] | 38 | static void print_types(void) |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 39 | { |
| 40 | unsigned int i; |
| 41 | |
| 42 | printf("Valid packet types:\n"); |
Jan Engelhardt | 2c69b55 | 2009-04-30 19:32:02 +0200 | [diff] [blame] | 43 | for (i = 0; i < ARRAY_SIZE(supported_types); ++i) |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 44 | if(supported_types[i].printhelp == 1) |
| 45 | printf("\t%-14s\t\t%s\n", supported_types[i].name, supported_types[i].help); |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 46 | printf("\n"); |
| 47 | } |
| 48 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 49 | static void pkttype_help(void) |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 50 | { |
| 51 | printf( |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 52 | "pkttype match options:\n" |
Jan Engelhardt | 9b488b9 | 2008-06-08 19:11:51 +0200 | [diff] [blame] | 53 | "[!] --pkt-type packettype match packet type\n"); |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 54 | print_types(); |
| 55 | } |
| 56 | |
Jan Engelhardt | de31da3 | 2011-03-02 19:19:16 +0100 | [diff] [blame] | 57 | static const struct xt_option_entry pkttype_opts[] = { |
| 58 | {.name = "pkt-type", .id = O_PKTTYPE, .type = XTTYPE_STRING, |
| 59 | .flags = XTOPT_MAND | XTOPT_INVERT}, |
| 60 | XTOPT_TABLEEND, |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 61 | }; |
| 62 | |
Yasuyuki KOZAKAI | 5fd6ec8 | 2007-07-24 07:05:45 +0000 | [diff] [blame] | 63 | static void parse_pkttype(const char *pkttype, struct xt_pkttype_info *info) |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 64 | { |
| 65 | unsigned int i; |
| 66 | |
Jan Engelhardt | 2c69b55 | 2009-04-30 19:32:02 +0200 | [diff] [blame] | 67 | for (i = 0; i < ARRAY_SIZE(supported_types); ++i) |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 68 | if(strcasecmp(pkttype, supported_types[i].name)==0) |
| 69 | { |
| 70 | info->pkttype=supported_types[i].pkttype; |
| 71 | return; |
| 72 | } |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 73 | |
Jan Engelhardt | 1829ed4 | 2009-02-21 03:29:44 +0100 | [diff] [blame] | 74 | xtables_error(PARAMETER_PROBLEM, "Bad packet type '%s'", pkttype); |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 75 | } |
| 76 | |
Jan Engelhardt | de31da3 | 2011-03-02 19:19:16 +0100 | [diff] [blame] | 77 | static void pkttype_parse(struct xt_option_call *cb) |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 78 | { |
Jan Engelhardt | de31da3 | 2011-03-02 19:19:16 +0100 | [diff] [blame] | 79 | struct xt_pkttype_info *info = cb->data; |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 80 | |
Jan Engelhardt | de31da3 | 2011-03-02 19:19:16 +0100 | [diff] [blame] | 81 | xtables_option_parse(cb); |
| 82 | parse_pkttype(cb->arg, info); |
| 83 | if (cb->invert) |
| 84 | info->invert = 1; |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 85 | } |
| 86 | |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 87 | static void print_pkttype(const struct xt_pkttype_info *info) |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 88 | { |
| 89 | unsigned int i; |
| 90 | |
Jan Engelhardt | 2c69b55 | 2009-04-30 19:32:02 +0200 | [diff] [blame] | 91 | for (i = 0; i < ARRAY_SIZE(supported_types); ++i) |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 92 | if(supported_types[i].pkttype==info->pkttype) |
| 93 | { |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 94 | printf("%s", supported_types[i].name); |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 95 | return; |
| 96 | } |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 97 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 98 | printf("%d", info->pkttype); /* in case we didn't find an entry in named-packtes */ |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 99 | } |
| 100 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 101 | static void pkttype_print(const void *ip, const struct xt_entry_match *match, |
| 102 | int numeric) |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 103 | { |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 104 | const struct xt_pkttype_info *info = (const void *)match->data; |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 105 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 106 | printf(" PKTTYPE %s= ", info->invert ? "!" : ""); |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 107 | print_pkttype(info); |
| 108 | } |
| 109 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 110 | static void pkttype_save(const void *ip, const struct xt_entry_match *match) |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 111 | { |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 112 | const struct xt_pkttype_info *info = (const void *)match->data; |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 113 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 114 | printf("%s --pkt-type ", info->invert ? " !" : ""); |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 115 | print_pkttype(info); |
| 116 | } |
| 117 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 118 | static struct xtables_match pkttype_match = { |
Jan Engelhardt | 4297936 | 2009-06-01 11:56:23 +0200 | [diff] [blame] | 119 | .family = NFPROTO_UNSPEC, |
Yasuyuki KOZAKAI | 5fd6ec8 | 2007-07-24 07:05:45 +0000 | [diff] [blame] | 120 | .name = "pkttype", |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 121 | .version = XTABLES_VERSION, |
Yasuyuki KOZAKAI | 5fd6ec8 | 2007-07-24 07:05:45 +0000 | [diff] [blame] | 122 | .size = XT_ALIGN(sizeof(struct xt_pkttype_info)), |
| 123 | .userspacesize = XT_ALIGN(sizeof(struct xt_pkttype_info)), |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 124 | .help = pkttype_help, |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 125 | .print = pkttype_print, |
| 126 | .save = pkttype_save, |
Jan Engelhardt | de31da3 | 2011-03-02 19:19:16 +0100 | [diff] [blame] | 127 | .x6_parse = pkttype_parse, |
| 128 | .x6_options = pkttype_opts, |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 129 | }; |
| 130 | |
| 131 | void _init(void) |
| 132 | { |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 133 | xtables_register_match(&pkttype_match); |
Harald Welte | b516647 | 2001-04-19 16:35:39 +0000 | [diff] [blame] | 134 | } |