libxt_devgroup.c revision 5d8e61ef4636383ca47cd748cd7457a238de37a6
19ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy/* Shared library add-on to iptables to add devgroup matching support. 29ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy * 39ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy * Copyright (c) 2011 Patrick McHardy <kaber@trash.net> 49ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy */ 59ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy#include <stdio.h> 69ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy#include <string.h> 79ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy#include <stdlib.h> 89ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy#include <errno.h> 99ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy#include <xtables.h> 109ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy#include <linux/netfilter/xt_devgroup.h> 119ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 129ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardystatic void devgroup_help(void) 139ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy{ 149ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy printf( 159ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy"devgroup match options:\n" 169ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy"[!] --src-group value[/mask] Match device group of incoming device\n" 179ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy"[!] --dst-group value[/mask] Match device group of outgoing device\n" 189ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy ); 199ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy} 209ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 219ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardyenum { 225d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt O_SRC_GROUP = 0, 235d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt O_DST_GROUP, 249ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy}; 259ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 265d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardtstatic const struct xt_option_entry devgroup_opts[] = { 275d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt {.name = "src-group", .id = O_SRC_GROUP, .type = XTTYPE_STRING, 285d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt .flags = XTOPT_INVERT}, 295d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt {.name = "dst-group", .id = O_DST_GROUP, .type = XTTYPE_STRING, 305d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt .flags = XTOPT_INVERT}, 315d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt XTOPT_TABLEEND, 329ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy}; 339ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 349ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy/* array of devgroups from /etc/iproute2/group_map */ 355d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardtstatic struct xtables_lmap *devgroups; 369ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 375d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardtstatic void devgroup_init(struct xt_entry_match *match) 389ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy{ 395d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt const char file[] = "/etc/iproute2/group_map"; 405d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt devgroups = xtables_lmap_init(file); 415d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt if (devgroups == NULL && errno != ENOENT) 425d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno)); 439ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy} 449ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 455d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardtstatic void devgroup_parse(struct xt_option_call *cb) 469ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy{ 475d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt struct xt_devgroup_info *info = cb->data; 489ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy unsigned int id; 499ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy char *end; 509ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 515d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt xtables_option_parse(cb); 525d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt switch (cb->entry->id) { 535d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt case O_SRC_GROUP: 545d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt info->src_group = strtoul(cb->arg, &end, 0); 555d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt if (end != cb->arg && (*end == '/' || *end == '\0')) { 569ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (*end == '/') 579ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy info->src_mask = strtoul(end+1, &end, 0); 589ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy else 599ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy info->src_mask = 0xffffffff; 605d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt if (*end != '\0' || end == cb->arg) 619ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy xtables_error(PARAMETER_PROBLEM, 629ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy "Bad src-group value `%s'", 635d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt cb->arg); 649ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy } else { 655d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt id = xtables_lmap_name2id(devgroups, cb->arg); 669ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (id == -1) 679ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy xtables_error(PARAMETER_PROBLEM, 689ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy "Device group `%s' not found", 695d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt cb->arg); 709ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy info->src_group = id; 719ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy info->src_mask = 0xffffffff; 729ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy } 735d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt if (cb->invert) 749ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy info->flags |= XT_DEVGROUP_INVERT_SRC; 759ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy break; 765d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt case O_DST_GROUP: 775d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt info->dst_group = strtoul(cb->arg, &end, 0); 785d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt if (end != cb->arg && (*end == '/' || *end == '\0')) { 799ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (*end == '/') 809ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy info->dst_mask = strtoul(end+1, &end, 0); 819ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy else 829ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy info->dst_mask = 0xffffffff; 835d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt if (*end != '\0' || end == cb->arg) 849ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy xtables_error(PARAMETER_PROBLEM, 859ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy "Bad dst-group value `%s'", 865d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt cb->arg); 879ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy } else { 885d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt id = xtables_lmap_name2id(devgroups, cb->arg); 899ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (id == -1) 909ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy xtables_error(PARAMETER_PROBLEM, 919ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy "Device group `%s' not found", 925d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt cb->arg); 939ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy info->dst_group = id; 949ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy info->dst_mask = 0xffffffff; 959ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy } 965d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt if (cb->invert) 979ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy info->flags |= XT_DEVGROUP_INVERT_DST; 989ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy break; 999ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy } 1009ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy} 1019ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1029ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardystatic void 1039ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardyprint_devgroup(unsigned int id, unsigned int mask, int numeric) 1049ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy{ 1059ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy const char *name = NULL; 1069ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1079ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (mask != 0xffffffff) 108c0f6d17764e9bc1724cedd78b880a80446363146Jan Engelhardt printf("0x%x/0x%x", id, mask); 1099ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy else { 1109ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (numeric == 0) 1115d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt name = xtables_lmap_id2name(devgroups, id); 1129ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (name) 113c0f6d17764e9bc1724cedd78b880a80446363146Jan Engelhardt printf("%s", name); 1149ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy else 115c0f6d17764e9bc1724cedd78b880a80446363146Jan Engelhardt printf("0x%x", id); 1169ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy } 1179ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy} 1189ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1199ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardystatic void devgroup_show(const char *pfx, const struct xt_devgroup_info *info, 1209ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy int numeric) 1219ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy{ 1229ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (info->flags & XT_DEVGROUP_MATCH_SRC) { 1239ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (info->flags & XT_DEVGROUP_INVERT_SRC) 124c0f6d17764e9bc1724cedd78b880a80446363146Jan Engelhardt printf(" !"); 125c0f6d17764e9bc1724cedd78b880a80446363146Jan Engelhardt printf(" %ssrc-group ", pfx); 1269ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy print_devgroup(info->src_group, info->src_mask, numeric); 1279ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy } 1289ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1299ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (info->flags & XT_DEVGROUP_MATCH_DST) { 1309ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy if (info->flags & XT_DEVGROUP_INVERT_DST) 131c0f6d17764e9bc1724cedd78b880a80446363146Jan Engelhardt printf(" !"); 132c0f6d17764e9bc1724cedd78b880a80446363146Jan Engelhardt printf(" %sdst-group ", pfx); 1339ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy print_devgroup(info->src_group, info->src_mask, numeric); 1349ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy } 1359ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy} 1369ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1379ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardystatic void devgroup_print(const void *ip, const struct xt_entry_match *match, 1389ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy int numeric) 1399ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy{ 1409ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy const struct xt_devgroup_info *info = (const void *)match->data; 1419ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1429ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy devgroup_show("", info, numeric); 1439ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy} 1449ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1459ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardystatic void devgroup_save(const void *ip, const struct xt_entry_match *match) 1469ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy{ 1479ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy const struct xt_devgroup_info *info = (const void *)match->data; 1489ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1499ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy devgroup_show("--", info, 0); 1509ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy} 1519ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1525d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardtstatic void devgroup_check(struct xt_fcheck_call *cb) 1539ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy{ 1545d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt if (cb->xflags == 0) 1559ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy xtables_error(PARAMETER_PROBLEM, 1569ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy "devgroup match: You must specify either " 1579ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy "'--src-group' or '--dst-group'"); 1589ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy} 1599ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1609ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardystatic struct xtables_match devgroup_mt_reg = { 1619ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy .name = "devgroup", 1629ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy .version = XTABLES_VERSION, 1639ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy .family = NFPROTO_UNSPEC, 1649ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy .size = XT_ALIGN(sizeof(struct xt_devgroup_info)), 1659ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy .userspacesize = XT_ALIGN(sizeof(struct xt_devgroup_info)), 1665d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt .init = devgroup_init, 1679ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy .help = devgroup_help, 1689ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy .print = devgroup_print, 1699ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy .save = devgroup_save, 1705d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt .x6_parse = devgroup_parse, 1715d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt .x6_fcheck = devgroup_check, 1725d8e61ef4636383ca47cd748cd7457a238de37a6Jan Engelhardt .x6_options = devgroup_opts, 1739ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy}; 1749ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy 1759ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardyvoid _init(void) 1769ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy{ 1779ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy xtables_register_match(&devgroup_mt_reg); 1789ee2a9fe2f74b616da34878104bd1ff406534ad1Patrick McHardy} 179