nft.c revision e17b5f15c2beda86565a8f4e55fdf12ceb20dd59
1384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* 2384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org> 3384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * 4384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * This program is free software; you can redistribute it and/or modify 5384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * it under the terms of the GNU General Public License as published 6384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * by the Free Software Foundation; either version 2 of the License, or 7384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * (at your option) any later version. 8384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * 9384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * This code has been sponsored by Sophos Astaro <http://www.sophos.com> 10384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso */ 11384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 12384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#if 0 13384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define DEBUGP(x, args...) fprintf(stdout, x, ## args) 14384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define NLDEBUG 15384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define DEBUG_DEL 16384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#else 17384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define DEBUGP(x, args...) 18384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 19384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 20384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <unistd.h> 21384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <fcntl.h> 22384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <sys/types.h> 23384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <sys/socket.h> 24384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <stdbool.h> 25384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <errno.h> 26384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <netdb.h> /* getprotobynumber */ 27384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <time.h> 28384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 29384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <xtables.h> 30384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libiptc/libxtc.h> 31384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libiptc/xtcshared.h> 32384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 33384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <stdlib.h> 34384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <string.h> 35384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 36384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netfilter/x_tables.h> 37384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netfilter_ipv4/ip_tables.h> /* FIXME: only IPV4 by now */ 38384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 39384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netlink.h> 40384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netfilter/nfnetlink.h> 41384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netfilter/nf_tables.h> 42384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netfilter/nf_tables_compat.h> 43384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 44384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libmnl/libmnl.h> 45384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libnftables/table.h> 46384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libnftables/chain.h> 47384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libnftables/rule.h> 48384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libnftables/expr.h> 49384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 50384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <netinet/in.h> /* inet_ntoa */ 51384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <arpa/inet.h> 52384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 53384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include "nft.h" 54384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include "xshared.h" /* proto_to_name */ 55384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 56384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void *nft_fn; 57384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 58384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh, 59384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int (*cb)(const struct nlmsghdr *nlh, void *data), 60384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *data) 61384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 62384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 63384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 64384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 65384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_sendto(h->nl, nlh, nlh->nlmsg_len) < 0) { 66384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_send"); 67384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 68384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 69384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 70384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf)); 71384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (ret > 0) { 72384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_cb_run(buf, ret, h->seq, h->portid, cb, data); 73384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret <= 0) 74384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 75384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 76384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf)); 77384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 78384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == -1) { 79384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 80384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 81384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 82384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 83384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 84384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 85e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayusostatic int nft_table_builtin_add(struct nft_handle *h, const char *table) 86384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 87384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 88384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 89384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table *t; 90e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int ret; 91384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 92384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_alloc(); 93384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (t == NULL) 94e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso return -1; 95384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 96c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso nft_table_attr_set(t, NFT_TABLE_ATTR_NAME, (char *)table); 97384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 98384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, AF_INET, 99384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 100384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_nlmsg_build_payload(nlh, t); 101384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_free(t); 102384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 103e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 104e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (ret < 0) { 105384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST) 106384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl-talk:nft_table_init_one"); 107384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 108e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso return ret; 109384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 110384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 111384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FILTER 0 112384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define MANGLE 1 113384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define RAW 2 114384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define SECURITY 3 115384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define TABLES_MAX 4 116384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 117e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayusostruct builtin_chain { 118e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso const char *name; 119e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso uint32_t hook; 120e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso}; 121e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 122c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic struct builtin_table { 123384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 124384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t prio; 125e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso struct builtin_chain chains[NF_INET_NUMHOOKS]; 126384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} tables[TABLES_MAX] = { 127384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [RAW] = { 128384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "raw", 129384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .prio = -300, /* NF_IP_PRI_RAW */ 130e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 131e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 132e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "PREROUTING", 133e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 134e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 135e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 136e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 137e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 138e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 139e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 140384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 141384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [MANGLE] = { 142384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "mangle", 143384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 144e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 145e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 146e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "PREROUTING", 147e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 148e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 149e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 150e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 151e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 152e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 153e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 154e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 155e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 156e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 157e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 158e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 159e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 160e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 161e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 162e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "POSTROUTING", 163e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_POST_ROUTING, 164e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 165e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 166384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 167384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [FILTER] = { 168384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "filter", 169384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .prio = 0, /* NF_IP_PRI_FILTER */ 170e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 171e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 172e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 173e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 174e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 175e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 176e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 177e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 178e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 179e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 180e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 181e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 182e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 183e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 184384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 185384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [SECURITY] = { 186384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "security", 187384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .prio = 150, /* NF_IP_PRI_SECURITY */ 188e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 189e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 190e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 191e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 192e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 193e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 194e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 195e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 196e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 197e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 198e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 199e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 200e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 201384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 202384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 203e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* nat already registered by nf_tables */ 204384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso}; 205384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 206c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic struct nft_chain * 207c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusonft_chain_builtin_alloc(struct builtin_table *table, 208c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *chain, int policy) 209384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 210384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 211384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 212384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_alloc(); 213384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (c == NULL) 214c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return NULL; 215384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 216384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table->name); 217384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)chain->name); 218384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_HOOKNUM, chain->hook); 219384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_PRIO, table->prio); 220384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY, policy); 221384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 222c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return c; 223c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 224c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 225c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic void 226c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusonft_chain_builtin_add(struct nft_handle *h, struct builtin_table *table, 227c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *chain, int policy) 228c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 229c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 230c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct nlmsghdr *nlh; 231c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct nft_chain *c; 232c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 233c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso c = nft_chain_builtin_alloc(table, chain, policy); 234c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (c == NULL) 235c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return; 236c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 237384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, AF_INET, 238384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 239384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 240384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 241384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 242384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_talk(h, nlh, NULL, NULL) < 0) { 243384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST) 244c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso perror("mnl_talk:nft_chain_builtin_add"); 245c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 246c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 247c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 248c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso/* find if built-in table already exists */ 249c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic struct builtin_table *nft_table_builtin_find(const char *table) 250c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 251c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso int i; 252c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso bool found = false; 253c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 254c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso for (i=0; i<TABLES_MAX; i++) { 255c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (strcmp(tables[i].name, table) != 0) 256c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso continue; 257c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 258c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso found = true; 259c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso break; 260384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 261c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 262c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return found ? &tables[i] : NULL; 263384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 264384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 265c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso/* find if built-in chain already exists */ 266c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic struct builtin_chain * 267e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayusonft_chain_builtin_find(struct builtin_table *t, const char *chain) 268384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 269e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int i; 270c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso bool found = false; 271384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 272e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso for (i=0; i<NF_IP_NUMHOOKS && t->chains[i].name != NULL; i++) { 273e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (strcmp(t->chains[i].name, chain) != 0) 274e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso continue; 275384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 276e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso found = true; 277e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso break; 278e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso } 279e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso return found ? &t->chains[i] : NULL; 280e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso} 281e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 282e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayusostatic void 283e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso__nft_chain_builtin_init(struct nft_handle *h, 284e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso struct builtin_table *table, const char *chain, 285e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int policy) 286e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso{ 287e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int i, default_policy; 288e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 289e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* Initialize all built-in chains. Exception, for e one received as 290e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso * parameter, set the default policy as requested. 291e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso */ 292e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso for (i=0; i<NF_IP_NUMHOOKS && table->chains[i].name != NULL; i++) { 293e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (chain && strcmp(table->chains[i].name, chain) == 0) 294e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso default_policy = policy; 295e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso else 296e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso default_policy = NF_ACCEPT; 297e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 298e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso nft_chain_builtin_add(h, table, &table->chains[i], 299e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso default_policy); 300384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 301c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 302c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 303c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic int 304c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusonft_chain_builtin_init(struct nft_handle *h, const char *table, 305c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso const char *chain, int policy) 306c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 307c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso int ret = 0; 308c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_table *t; 309c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 310c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso t = nft_table_builtin_find(table); 311c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (t == NULL) { 312c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso ret = -1; 313c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso goto out; 314c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 315e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (nft_table_builtin_add(h, table) < 0) { 316e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* Built-in table already initialized, skip. */ 317e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (errno == EEXIST) 318e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso goto out; 319c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 320e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso __nft_chain_builtin_init(h, t, chain, policy); 321c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusoout: 322c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return ret; 323384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 324384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 325384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_init(struct nft_handle *h) 326384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 327384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso h->nl = mnl_socket_open(NETLINK_NETFILTER); 328384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (h->nl == NULL) { 329384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_open"); 330384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 331384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 332384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 333384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_bind(h->nl, 0, MNL_SOCKET_AUTOPID) < 0) { 334384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_bind"); 335384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 336384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 337384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso h->portid = mnl_socket_get_portid(h->nl); 338384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 339384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 340384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 341384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 342384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusovoid nft_fini(struct nft_handle *h) 343384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 344384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_socket_close(h->nl); 345384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 346384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 347384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_table_add(struct nft_handle *h, const struct nft_table *t) 348384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 349384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 350384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 351384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 352384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, AF_INET, 353384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 354384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_nlmsg_build_payload(nlh, t); 355384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 356384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return mnl_talk(h, nlh, NULL, NULL); 357384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 358384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 359384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_add(struct nft_handle *h, const struct nft_chain *c) 360384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 361384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 362384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 363384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 364384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, AF_INET, 365384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 366384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 367384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 368384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return mnl_talk(h, nlh, NULL, NULL); 369384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 370384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 371384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_chain_print_debug(struct nft_chain *c, struct nlmsghdr *nlh) 372384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 373384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef NLDEBUG 374384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char tmp[1024]; 375384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 376384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_snprintf(tmp, sizeof(tmp), c, 0, 0); 377384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("DEBUG: chain: %s", tmp); 378384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 379384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 380384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 381384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 382384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 383384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_chain_set(struct nft_handle *h, const char *table, 384384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain, int policy, 385384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_counters *counters) 386384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 387384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 388384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 389384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 390c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_table *_t; 391c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *_c; 392e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int ret; 393c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 394c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso _t = nft_table_builtin_find(table); 395c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso /* if this built-in table does not exists, create it */ 396c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (_t != NULL) 397c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso nft_table_builtin_add(h, table); 398c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 399e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso _c = nft_chain_builtin_find(_t, chain); 400c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (_c != NULL) { 401c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso /* This is a built-in chain */ 402c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso c = nft_chain_builtin_alloc(_t, _c, policy); 403c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (c == NULL) 404c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return -1; 405c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 406c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } else { 407c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso /* This is a custom chain */ 408c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso c = nft_chain_alloc(); 409c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (c == NULL) 410c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return -1; 411c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 412c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table); 413c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)chain); 414c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY, policy); 415c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 416384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 417384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (counters) { 418384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_BYTES, 419384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->bcnt); 420384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS, 421384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->pcnt); 422384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 423384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 424384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, AF_INET, 425384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 426384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 427384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 428384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_print_debug(c, nlh); 429384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 430384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 431384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 432384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 433384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 434384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:__nft_chain_policy"); 435384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 436384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 437384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 438384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 439384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_set(struct nft_handle *h, const char *table, 440384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain, const char *policy, 441384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_counters *counters) 442384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 443384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = -1; 444384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 445384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_chain_set; 446384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 447384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(policy, "DROP") == 0) 448384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = __nft_chain_set(h, table, chain, NF_DROP, counters); 449384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else if (strcmp(policy, "ACCEPT") == 0) 450384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = __nft_chain_set(h, table, chain, NF_ACCEPT, counters); 451384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 452384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 453384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 454384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 455384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 456384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void __add_match(struct nft_rule_expr *e, struct xt_entry_match *m) 457384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 458384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *info; 459384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 460384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_MT_NAME, m->u.user.name, strlen(m->u.user.name)); 461384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(e, NFT_EXPR_MT_REV, m->u.user.revision); 462384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 463384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso info = calloc(1, m->u.match_size); 464384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (info == NULL) 465384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 466384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 467384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(info, m->data, m->u.match_size); 468384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_MT_INFO, info, m->u.match_size - sizeof(*m)); 469384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 470384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 471384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void add_match(struct nft_rule *r, struct xt_entry_match *m) 472384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 473384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 474384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 475384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("match"); 476384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 477384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 478384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 479384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso __add_match(expr, m); 480384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 481384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 482384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 483384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void __add_target(struct nft_rule_expr *e, struct xt_entry_target *t) 484384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 485384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *info = NULL; 486384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 487384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_TG_NAME, t->u.user.name, 488384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strlen(t->u.user.name)); 489384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(e, NFT_EXPR_TG_REV, t->u.user.revision); 490384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 491384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (info == NULL) { 492384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso info = calloc(1, t->u.target_size); 493384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (info == NULL) 494384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 495384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 496384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(info, t->data, t->u.target_size); 497384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 498384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 499384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_TG_INFO, info, t->u.target_size - sizeof(*t)); 500384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 501384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 502384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void add_target(struct nft_rule *r, struct xt_entry_target *t) 503384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 504384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 505384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 506384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("target"); 507384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 508384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 509384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 510384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso __add_target(expr, t); 511384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 512384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 513384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 514384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void add_jumpto(struct nft_rule *r, const char *name, int verdict) 515384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 516384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 517384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 518384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("immediate"); 519384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 520384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 521384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 522384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_DREG, NFT_REG_VERDICT); 523384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_VERDICT, verdict); 524384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_str(expr, NFT_EXPR_IMM_CHAIN, (char *)name); 525384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 526384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 527384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 528384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void add_verdict(struct nft_rule *r, int verdict) 529384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 530384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 531384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 532384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("immediate"); 533384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 534384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 535384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 536384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_DREG, NFT_REG_VERDICT); 537384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_VERDICT, verdict); 538384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 539384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 540384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 541384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_rule_print_debug(struct nft_rule *r, struct nlmsghdr *nlh) 542384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 543384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef NLDEBUG 544384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char tmp[1024]; 545384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 546384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_snprintf(tmp, sizeof(tmp), r, 0, 0); 547384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("DEBUG: rule: %s", tmp); 548384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 549384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 550384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 551384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 552384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void add_meta(struct nft_rule *r, uint32_t key) 553384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 554384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 555384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 556384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("meta"); 557384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 558384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 559384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 560384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_META_KEY, key); 561384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_META_DREG, NFT_REG_1); 562384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 563384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 564384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 565384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 566384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void add_payload(struct nft_rule *r, int offset, int len) 567384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 568384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 569384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 570384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("payload"); 571384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 572384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 573384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 574384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_PAYLOAD_BASE, 575384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NFT_PAYLOAD_NETWORK_HEADER); 576384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_PAYLOAD_DREG, NFT_REG_1); 577384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_PAYLOAD_OFFSET, offset); 578384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_PAYLOAD_LEN, len); 579384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 580384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 581384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 582384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 583384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void add_cmp_ptr(struct nft_rule *r, uint32_t op, void *data, size_t len) 584384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 585384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 586384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 587384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("cmp"); 588384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 589384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 590384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 591384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u8(expr, NFT_EXPR_CMP_SREG, NFT_REG_1); 592384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u8(expr, NFT_EXPR_CMP_OP, op); 593384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(expr, NFT_EXPR_CMP_DATA, data, len); 594384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 595384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 596384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 597384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 598384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void add_cmp_u32(struct nft_rule *r, uint32_t val, uint32_t op) 599384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 600384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_cmp_ptr(r, op, &val, sizeof(val)); 601384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 602384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 603384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void add_counters(struct nft_rule *r, uint64_t packets, uint64_t bytes) 604384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 605384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 606384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 607384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("counter"); 608384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 609384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 610384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 611384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u64(expr, NFT_EXPR_CTR_BYTES, packets); 612384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u64(expr, NFT_EXPR_CTR_PACKETS, bytes); 613384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 614384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 615384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 616384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 617384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint 618384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_rule_add(struct nft_handle *h, const char *chain, const char *table, 619384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct iptables_command_state *cs, bool append, bool verbose) 620384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 621384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 622384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 623384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xtables_rule_match *matchp; 624384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 625384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 1; 626384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t op; 627384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int flags = append ? NLM_F_APPEND : 0; 628384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 629e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* If built-in chains don't exist for this table, create them */ 630c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso nft_chain_builtin_init(h, table, chain, NF_ACCEPT); 631c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 632384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_add; 633384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 634384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_alloc(); 635384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (r == NULL) { 636384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 0; 637384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 638384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 639384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 640384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, (char *)table); 641384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, (char *)chain); 642384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 643384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.iniface[0] != '\0') { 644384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int iface_len = strlen(cs->fw.ip.iniface); 645384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 646384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.invflags & IPT_INV_VIA_IN) 647384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = NFT_CMP_NEQ; 648384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 649384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = NFT_CMP_EQ; 650384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 651384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.iniface[iface_len - 1] == '+') { 652384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_meta(r, NFT_META_IIFNAME); 653384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_cmp_ptr(r, op, cs->fw.ip.iniface, iface_len - 1); 654384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 655384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_meta(r, NFT_META_IIF); 656384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_cmp_u32(r, if_nametoindex(cs->fw.ip.iniface), op); 657384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 658384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 659384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.outiface[0] != '\0') { 660384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int iface_len = strlen(cs->fw.ip.outiface); 661384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 662384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.invflags & IPT_INV_VIA_OUT) 663384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = NFT_CMP_NEQ; 664384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 665384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = NFT_CMP_EQ; 666384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 667384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.outiface[iface_len - 1] == '+') { 668384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_meta(r, NFT_META_OIFNAME); 669384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_cmp_ptr(r, op, cs->fw.ip.outiface, iface_len - 1); 670384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 671384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_meta(r, NFT_META_OIF); 672384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_cmp_u32(r, if_nametoindex(cs->fw.ip.outiface), op); 673384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 674384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 675384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.src.s_addr != 0) { 676384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_payload(r, offsetof(struct iphdr, saddr), 4); 677384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.invflags & IPT_INV_SRCIP) 678384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = NFT_CMP_NEQ; 679384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 680384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = NFT_CMP_EQ; 681384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 682384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_cmp_u32(r, cs->fw.ip.src.s_addr, op); 683384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 684384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.dst.s_addr != 0) { 685384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_payload(r, offsetof(struct iphdr, daddr), 4); 686384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.invflags & IPT_INV_DSTIP) 687384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = NFT_CMP_NEQ; 688384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 689384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = NFT_CMP_EQ; 690384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 691384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_cmp_u32(r, cs->fw.ip.dst.s_addr, op); 692384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 693384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.proto != 0) { 694384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_payload(r, offsetof(struct iphdr, protocol), 1); 695384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.invflags & XT_INV_PROTO) 696384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = NFT_CMP_NEQ; 697384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 698384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = NFT_CMP_EQ; 699384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 700384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_cmp_u32(r, cs->fw.ip.proto, op); 701384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 702384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 703384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (matchp = cs->matches; matchp; matchp = matchp->next) 704384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_match(r, matchp->match->m); 705384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 706384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Counters need to me added before the target, otherwise they are 707384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * increased for each rule because of the way nf_tables works. 708384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso */ 709384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_counters(r, cs->counters.pcnt, cs->counters.bcnt); 710384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 711384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* If no target at all, add nothing (default to continue) */ 712384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->target != NULL) { 713384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Standard target? */ 714384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0) 715384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_verdict(r, NF_ACCEPT); 716384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0) 717384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_verdict(r, NF_DROP); 718384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0) 719384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_verdict(r, NFT_RETURN); 720384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 721384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_target(r, cs->target->t); 722384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strlen(cs->jumpto) > 0) { 723384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Not standard, then it's a go / jump to chain */ 724384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.flags & IPT_F_GOTO) 725384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_jumpto(r, cs->jumpto, NFT_GOTO); 726384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 727384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso add_jumpto(r, cs->jumpto, NFT_JUMP); 728384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 729384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 730384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* NLM_F_CREATE autoloads the built-in table if it does not exists */ 731384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 732384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_CREATE|flags, h->seq); 733384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_nlmsg_build_payload(nlh, r); 734384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 735384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_print_debug(r, nlh); 736384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 737384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_free(r); 738384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 739384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 740384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 741384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_rule_add"); 742384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 743384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 744384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 745384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 746384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 747384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 748384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_match_save(struct nft_rule_expr *expr) 749384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 750384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 751384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xtables_match *match; 752384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_entry_match *emu; 753384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const void *mtinfo; 754384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 755384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 756384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name = nft_rule_expr_get_str(expr, NFT_EXPR_MT_NAME); 757384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 758384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso match = xtables_find_match(name, XTF_TRY_LOAD, NULL); 759384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (match == NULL) 760384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 761384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 762384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mtinfo = nft_rule_expr_get(expr, NFT_EXPR_MT_INFO, &len); 763384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mtinfo == NULL) 764384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 765384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 766384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso emu = calloc(1, sizeof(struct xt_entry_match) + len); 767384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (emu == NULL) 768384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 769384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 770384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(&emu->data, mtinfo, len); 771384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 772384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (match->alias) 773384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-m %s", match->alias(emu)); 774384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 775384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-m %s", match->name); 776384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 777384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* FIXME missing parameter */ 778384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso match->save(NULL, emu); 779384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 780384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(" "); 781384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 782384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso free(emu); 783384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 784384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 785384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_target_save(struct nft_rule_expr *expr) 786384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 787384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 788384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xtables_target *target; 789384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_entry_target *emu; 790384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const void *tginfo; 791384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 792384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 793384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name = nft_rule_expr_get_str(expr, NFT_EXPR_TG_NAME); 794384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 795384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Standard target not supported, we use native immediate expression */ 796384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "") == 0) { 797384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("ERROR: standard target seen, should not happen\n"); 798384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 799384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 800384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 801384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso target = xtables_find_target(name, XTF_TRY_LOAD); 802384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (target == NULL) 803384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 804384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 805384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso tginfo = nft_rule_expr_get(expr, NFT_EXPR_TG_INFO, &len); 806384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (tginfo == NULL) 807384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 808384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 809384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso emu = calloc(1, sizeof(struct xt_entry_match) + len); 810384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (emu == NULL) 811384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 812384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 813384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(emu->data, tginfo, len); 814384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 815384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (target->alias) 816384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j %s", target->alias(emu)); 817384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 818384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j %s", target->name); 819384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 820384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* FIXME missing parameter */ 821384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso target->save(NULL, emu); 822384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 823384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso free(emu); 824384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 825384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 826384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_immediate_save(struct nft_rule_expr *expr) 827384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 828384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t verdict; 829384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 830384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso verdict = nft_rule_expr_get_u32(expr, NFT_EXPR_IMM_VERDICT); 831384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 832384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(verdict) { 833384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_ACCEPT: 834384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j ACCEPT"); 835384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 836384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_DROP: 837384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j DROP"); 838384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 839384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_RETURN: 840384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j RETURN"); 841384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 842384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_GOTO: 843384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-g %s", 844384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_EXPR_IMM_CHAIN)); 845384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 846384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_JUMP: 847384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j %s", 848384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_EXPR_IMM_CHAIN)); 849384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 850384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 851384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 852384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 853384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 854384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_print_meta(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter) 855384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 856384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint8_t key = nft_rule_expr_get_u8(e, NFT_EXPR_META_KEY); 857384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t value; 858384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 859384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char ifname[IFNAMSIZ]; 860384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *ifname_ptr; 861384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 862384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 863384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso e = nft_rule_expr_iter_next(iter); 864384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (e == NULL) 865384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 866384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 867384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name = nft_rule_expr_get_str(e, NFT_RULE_EXPR_ATTR_NAME); 868384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* meta should be followed by cmp */ 869384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "cmp") != 0) { 870384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("skipping no cmp after meta\n"); 871384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 872384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 873384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 874384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(key) { 875384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_IIF: 876384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso value = nft_rule_expr_get_u32(e, NFT_EXPR_CMP_DATA); 877384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if_indextoname(value, ifname); 878384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 879384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) { 880384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_EQ: 881384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-i %s ", ifname); 882384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 883384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_NEQ: 884384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! -i %s ", ifname); 885384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 886384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 887384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 888384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_OIF: 889384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso value = nft_rule_expr_get_u32(e, NFT_EXPR_CMP_DATA); 890384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if_indextoname(value, ifname); 891384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 892384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) { 893384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_EQ: 894384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-o %s ", ifname); 895384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 896384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_NEQ: 897384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! -o %s ", ifname); 898384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 899384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 900384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 901384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_IIFNAME: 902384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname_ptr = nft_rule_expr_get(e, NFT_EXPR_CMP_DATA, &len); 903384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(ifname, ifname_ptr, len); 904384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len] = '\0'; 905384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 906384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* if this is zero, then assume this is a interface mask */ 907384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (if_nametoindex(ifname) == 0) { 908384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len] = '+'; 909384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len+1] = '\0'; 910384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 911384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 912384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) { 913384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_EQ: 914384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-i %s ", ifname); 915384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 916384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_NEQ: 917384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! -i %s ", ifname); 918384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 919384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 920384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 921384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_OIFNAME: 922384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname_ptr = nft_rule_expr_get(e, NFT_EXPR_CMP_DATA, &len); 923384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(ifname, ifname_ptr, len); 924384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len] = '\0'; 925384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 926384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* if this is zero, then assume this is a interface mask */ 927384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (if_nametoindex(ifname) == 0) { 928384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len] = '+'; 929384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len+1] = '\0'; 930384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 931384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 932384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) { 933384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_EQ: 934384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-o %s ", ifname); 935384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 936384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_NEQ: 937384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! -o %s ", ifname); 938384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 939384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 940384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 941384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso default: 942384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("unknown meta key %d\n", key); 943384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 944384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 945384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 946384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 947384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 948384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoget_cmp_data(struct nft_rule_expr_iter *iter, void *data, size_t dlen, bool *inv) 949384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 950384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *e; 951384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 952384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 953384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint8_t op; 954384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 955384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso e = nft_rule_expr_iter_next(iter); 956384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (e == NULL) 957384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 958384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 959384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name = nft_rule_expr_get_str(e, NFT_RULE_EXPR_ATTR_NAME); 960384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "cmp") != 0) { 961384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("skipping no cmp after meta\n"); 962384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 963384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 964384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 965384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(data, nft_rule_expr_get(e, NFT_EXPR_CMP_DATA, &len), dlen); 966384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso op = nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP); 967384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (op == NFT_CMP_NEQ) 968384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso *inv = true; 969384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 970384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso *inv = false; 971384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 972384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 973384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void print_proto(uint16_t proto, int invert) 974384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 975384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct protoent *pent = getprotobynumber(proto); 976384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 977384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (invert) 978384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! "); 979384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 980384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (pent) { 981384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-p %s ", pent->p_name); 982384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 983384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 984384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 985384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-p %u ", proto); 986384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 987384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 988384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic const char *mask_to_str(uint32_t mask) 989384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 990384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso static char mask_str[sizeof("255.255.255.255")]; 991384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t bits, hmask = ntohl(mask); 992384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct in_addr mask_addr = { 993384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .s_addr = mask, 994384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }; 995384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int i; 996384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 997384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mask == 0xFFFFFFFFU) { 998384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso sprintf(mask_str, "32"); 999384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return mask_str; 1000384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1001384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1002384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso i = 32; 1003384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bits = 0xFFFFFFFEU; 1004384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (--i >= 0 && hmask != bits) 1005384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bits <<= 1; 1006384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (i >= 0) 1007384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso sprintf(mask_str, "%u", i); 1008384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 1009384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso sprintf(mask_str, "%s", inet_ntoa(mask_addr)); 1010384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1011384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return mask_str; 1012384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1013384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1014384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1015384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_print_payload(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter) 1016384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1017384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t offset; 1018384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool inv; 1019384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1020384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso offset = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_OFFSET); 1021384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1022384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(offset) { 1023384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct in_addr addr; 1024384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint8_t proto; 1025384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1026384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case offsetof(struct iphdr, saddr): 1027384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso get_cmp_data(iter, &addr, sizeof(addr), &inv); 1028384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (inv) 1029384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! -s %s/%s ", inet_ntoa(addr), 1030384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mask_to_str(0xffffffff)); 1031384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 1032384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-s %s/%s ", inet_ntoa(addr), 1033384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mask_to_str(0xffffffff)); 1034384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1035384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case offsetof(struct iphdr, daddr): 1036384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso get_cmp_data(iter, &addr, sizeof(addr), &inv); 1037384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (inv) 1038384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! -d %s/%s ", inet_ntoa(addr), 1039384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mask_to_str(0xffffffff)); 1040384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 1041384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-d %s/%s ", inet_ntoa(addr), 1042384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mask_to_str(0xffffffff)); 1043384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1044384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case offsetof(struct iphdr, protocol): 1045384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso get_cmp_data(iter, &proto, sizeof(proto), &inv); 1046384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_proto(proto, inv); 1047384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1048384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso default: 1049384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("unknown payload offset %d\n", offset); 1050384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1051384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1052384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1053384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1054384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1055384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_print_counters(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter, 1056384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool counters) 1057384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1058384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (counters) { 1059384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-c %lu %lu ", 1060384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_u64(e, NFT_EXPR_CTR_PACKETS), 1061384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_u64(e, NFT_EXPR_CTR_BYTES)); 1062384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1063384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1064384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1065384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_rule_print_save(struct nft_rule *r, bool counters) 1066384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1067384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 1068384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 1069384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1070384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* print chain name */ 1071384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-A %s ", nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN)); 1072384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1073384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 1074384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) 1075384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1076384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1077384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1078384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 1079384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 1080384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 1081384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1082384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "counter") == 0) { 1083384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_print_counters(expr, iter, counters); 1084384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "payload") == 0) { 1085384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_print_payload(expr, iter); 1086384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "meta") == 0) { 1087384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_print_meta(expr, iter); 1088384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "match") == 0) { 1089384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_match_save(expr); 1090384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "target") == 0) { 1091384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_target_save(expr); 1092384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "immediate") == 0) { 1093384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_immediate_save(expr); 1094384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1095384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1096384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1097384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1098384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1099384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("\n"); 1100384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1101384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1102384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int nft_chain_list_cb(const struct nlmsghdr *nlh, void *data) 1103384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1104384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1105384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list = data; 1106384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1107384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_alloc(); 1108384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (c == NULL) { 1109384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("OOM"); 1110384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1111384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1112384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1113384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_nlmsg_parse(nlh, c) < 0) { 1114384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("nft_rule_nlmsg_parse"); 1115384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1116384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1117384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1118384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_add(c, list); 1119384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1120384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1121384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1122384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 1123384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1124384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1125384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1126384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1127384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic struct nft_chain_list *nft_chain_list_get(struct nft_handle *h) 1128384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1129384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1130384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1131384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1132384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 1133384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1134384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_list_alloc(); 1135384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1136384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list\n"); 1137384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1138384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1139384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1140384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, AF_INET, 1141384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1142384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1143384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, nft_chain_list_cb, list); 1144384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1145384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_chain_list_get"); 1146384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1147384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1148384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1149384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1150384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostruct nft_chain_list *nft_chain_dump(struct nft_handle *h) 1151384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1152384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return nft_chain_list_get(h); 1153384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1154384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1155384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic const char *policy_name[NF_ACCEPT+1] = { 1156384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [NF_DROP] = "DROP", 1157384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [NF_ACCEPT] = "ACCEPT", 1158384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso}; 1159384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1160384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_chain_print_save(struct nft_chain *c, bool basechain) 1161384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1162384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain = nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 1163384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint64_t pkts = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS); 1164384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint64_t bytes = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES); 1165384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1166384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* print chain name */ 1167384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (basechain) { 1168384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t pol = NF_ACCEPT; 1169384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1170384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* no default chain policy? don't crash, display accept */ 1171384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_POLICY)) 1172384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso pol = nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY); 1173384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1174384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(":%s %s [%lu:%lu]\n", chain, policy_name[pol], 1175384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso pkts, bytes); 1176384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 1177384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(":%s - [%lu:%lu]\n", chain, pkts, bytes); 1178384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1179384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1180384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_save(struct nft_handle *h, struct nft_chain_list *list, 1181384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table) 1182384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1183384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 1184384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1185384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1186384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1187384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 1188384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 1189384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1190384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1191384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1192384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1193384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1194384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 1195384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 1196384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool basechain = false; 1197384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1198384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 1199384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1200384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1201384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM)) 1202384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso basechain = true; 1203384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1204384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_print_save(c, basechain); 1205384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1206384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1207384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1208384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1209384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 1210384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1211384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1212384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1213384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1214384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int nft_rule_list_cb(const struct nlmsghdr *nlh, void *data) 1215384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1216384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 1217384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list = data; 1218384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1219384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_alloc(); 1220384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (r == NULL) { 1221384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("OOM"); 1222384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1223384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1224384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1225384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_rule_nlmsg_parse(nlh, r) < 0) { 1226384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("nft_rule_nlmsg_parse"); 1227384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1228384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1229384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1230384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_add(r, list); 1231384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1232384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1233384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1234384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_free(r); 1235384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1236384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1237384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1238384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1239384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic struct nft_rule_list *nft_rule_list_get(struct nft_handle *h) 1240384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1241384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1242384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1243384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list; 1244384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1245384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1246384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_alloc(); 1247384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1248384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list\n"); 1249384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1250384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1251384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1252384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, AF_INET, 1253384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1254384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1255384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, nft_rule_list_cb, list); 1256384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) { 1257384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_rule_save"); 1258384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_free(list); 1259384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return NULL; 1260384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1261384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1262384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1263384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1264384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1265384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_save(struct nft_handle *h, const char *table, bool counters) 1266384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1267384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list; 1268384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list_iter *iter; 1269384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 1270384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1271384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_get(h); 1272384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1273384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot retrieve rule list from kernel\n"); 1274384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1275384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1276384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1277384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_list_iter_create(list); 1278384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 1279384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 1280384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1281384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1282384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1283384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 1284384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 1285384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 1286384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE); 1287384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1288384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0) 1289384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1290384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1291384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_print_save(r, counters); 1292384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1293384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1294384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 1295384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1296384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1297384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_free(list); 1298384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1299384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1300384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1301384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1302384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1303384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1304384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_rule_flush(struct nft_handle *h, const char *table, const char *chain) 1305384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1306384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1307384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1308384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 1309384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1310384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_alloc(); 1311384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (r == NULL) 1312384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1313384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1314384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, (char *)table); 1315384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, (char *)chain); 1316384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1317384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Delete all rules in this table + chain */ 1318384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_DELRULE, AF_INET, 1319384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 1320384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_nlmsg_build_payload(nlh, r); 1321384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_free(r); 1322384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1323384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_talk(h, nlh, NULL, NULL) < 0) { 1324384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST) 1325384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:__nft_rule_flush"); 1326384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1327384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1328384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1329384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) 1330384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1331384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1332384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 1333384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 1334384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1335384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1336384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_flush; 1337384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1338384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_list_get(h); 1339384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1340384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 0; 1341384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1342384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1343384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1344384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1345384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 1346384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 1347384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1348384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1349384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1350384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1351384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1352384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table_name = 1353384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 1354384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 1355384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 1356384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1357384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 1358384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1359384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1360384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain != NULL && strcmp(chain, chain_name) != 0) 1361384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1362384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1363384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso __nft_rule_flush(h, table_name, chain_name); 1364384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1365384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1366384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1367384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1368384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1369384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1370384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 1371384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1372384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1373384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1374384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1375384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1376384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table) 1377384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1378384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1379384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1380384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1381384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1382384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1383e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* If built-in chains don't exist for this table, create them */ 1384e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso nft_chain_builtin_init(h, table, NULL, NF_ACCEPT); 1385e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 1386384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_alloc(); 1387384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (c == NULL) { 1388384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate chain\n"); 1389384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 1390384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1391384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1392384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table); 1393384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)chain); 1394384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1395384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, AF_INET, 1396384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 1397384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 1398384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 1399384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1400384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 1401384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) { 1402384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST) 1403384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_chain_add"); 1404384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1405384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1406384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1407384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1408384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1409384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1410384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int __nft_chain_del(struct nft_handle *h, struct nft_chain *c) 1411384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1412384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1413384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1414384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1415384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1416384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_DELCHAIN, AF_INET, 1417384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 1418384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 1419384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1420384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 1421384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) { 1422384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST && errno != ENOENT) 1423384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:__nft_chain_del"); 1424384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1425384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1426384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 1427384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1428384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1429384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool nft_chain_builtin(struct nft_chain *c) 1430384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1431384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Check if this chain has hook number, in that case is built-in. 1432384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * Should we better export the flags to user-space via nf_tables? 1433384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso */ 1434384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM) != NULL; 1435384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1436384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1437384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table) 1438384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1439384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 1440384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 1441384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1442384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 0; 1443384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int deleted_ctr = 0; 1444384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1445384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_list_get(h); 1446384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) 1447384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1448384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1449384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1450384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 1451384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 1452384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1453384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1454384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1455384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1456384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1457384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table_name = 1458384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 1459384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 1460384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 1461384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1462384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* don't delete built-in chain */ 1463384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_builtin(c)) 1464384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1465384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1466384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 1467384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1468384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1469384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain != NULL && strcmp(chain, chain_name) != 0) 1470384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1471384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1472384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = __nft_chain_del(h, c); 1473384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1474384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1475384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1476384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso deleted_ctr++; 1477384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1478384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1479384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1480384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1481384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1482384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 1483384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1484384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* chain not found */ 1485384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0 && deleted_ctr == 0) 1486384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso errno = ENOENT; 1487384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1488384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1489384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1490384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1491384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1492384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_rename(struct nft_handle *h,const char *chain, 1493384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, const char *newname) 1494384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1495384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1496384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1497384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* XXX need new operation in nf_tables to support this */ 1498384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = nft_chain_user_del(h, chain, table); 1499384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1500384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 1501384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1502384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return nft_chain_user_add(h, newname, table); 1503384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1504384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1505384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int nft_table_list_cb(const struct nlmsghdr *nlh, void *data) 1506384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1507384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table *t; 1508384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list = data; 1509384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1510384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_alloc(); 1511384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (t == NULL) { 1512384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("OOM"); 1513384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1514384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1515384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1516384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_table_nlmsg_parse(nlh, t) < 0) { 1517384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("nft_rule_nlmsg_parse"); 1518384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1519384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1520384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1521384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_list_add(t, list); 1522384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1523384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1524384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1525384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_free(t); 1526384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1527384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1528384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1529384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1530384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic struct nft_table_list *nft_table_list_get(struct nft_handle *h) 1531384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1532384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1533384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1534384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1535384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list; 1536384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1537384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_table_list_alloc(); 1538384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1539384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate table list\n"); 1540384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1541384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1542384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1543384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, AF_INET, 1544384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1545384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1546384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, nft_table_list_cb, list); 1547384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1548384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_table_list_get"); 1549384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1550384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1551384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1552384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1553384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusobool nft_table_find(struct nft_handle *h, const char *tablename) 1554384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1555384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list; 1556384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list_iter *iter; 1557384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table *t; 1558384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool ret = false; 1559384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1560384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_table_list_get(h); 1561384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) 1562384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1563384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1564384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_table_list_iter_create(list); 1565384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 1566384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 1567384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1568384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1569384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1570384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1571384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (t != NULL) { 1572384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *this_tablename = 1573384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_attr_get(t, NFT_TABLE_ATTR_NAME); 1574384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1575384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(tablename, this_tablename) == 0) 1576384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1577384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1578384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1579384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1580384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1581384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_list_free(list); 1582384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1583384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1584384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 1585384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1586384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1587384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_for_each_table(struct nft_handle *h, 1588384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int (*func)(struct nft_handle *h, const char *tablename, bool counters), 1589384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool counters) 1590384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1591384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 1; 1592384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list; 1593384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list_iter *iter; 1594384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table *t; 1595384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1596384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_table_list_get(h); 1597384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1598384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 0; 1599384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1600384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1601384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1602384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_table_list_iter_create(list); 1603384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 1604384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 1605384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1606384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1607384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1608384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1609384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (t != NULL) { 1610384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *tablename = 1611384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_attr_get(t, NFT_TABLE_ATTR_NAME); 1612384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1613384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso func(h, tablename, counters); 1614384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1615384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1616384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1617384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1618384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_list_free(list); 1619384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1620384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1621384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1622384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1623384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1624384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1625384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic inline int 1626384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusomatch_different(const struct xt_entry_match *a, 1627384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const unsigned char *a_elems, 1628384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const unsigned char *b_elems, 1629384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned char **maskptr) 1630384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1631384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_entry_match *b; 1632384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int i; 1633384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1634384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Offset of b is the same as a. */ 1635384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso b = (void *)b_elems + ((unsigned char *)a - a_elems); 1636384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1637384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (a->u.match_size != b->u.match_size) 1638384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1639384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1640384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(a->u.user.name, b->u.user.name) != 0) 1641384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1642384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1643384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso *maskptr += XT_ALIGN(sizeof(*a)); 1644384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1645384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (i = 0; i < a->u.match_size - XT_ALIGN(sizeof(*a)); i++) 1646384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (((a->data[i] ^ b->data[i]) & (*maskptr)[i]) != 0) 1647384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1648384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso *maskptr += i; 1649384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1650384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1651384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1652384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool 1653384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusois_same(const struct iptables_command_state *a, const struct iptables_command_state *b) 1654384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1655384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int i; 1656384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1657384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Always compare head structures: ignore mask here. */ 1658384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (a->fw.ip.src.s_addr != b->fw.ip.src.s_addr 1659384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso || a->fw.ip.dst.s_addr != b->fw.ip.dst.s_addr 1660384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso || a->fw.ip.smsk.s_addr != b->fw.ip.smsk.s_addr 1661384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso || a->fw.ip.dmsk.s_addr != b->fw.ip.dmsk.s_addr 1662384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso || a->fw.ip.proto != b->fw.ip.proto 1663384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso || a->fw.ip.flags != b->fw.ip.flags 1664384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso || a->fw.ip.invflags != b->fw.ip.invflags) { 1665384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("different src/dst/proto/flags/invflags\n"); 1666384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1667384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1668384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1669384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (i = 0; i < IFNAMSIZ; i++) { 1670384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (a->fw.ip.iniface_mask[i] != b->fw.ip.iniface_mask[i]) { 1671384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("different iniface mask %x, %x (%d)\n", 1672384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso a->fw.ip.iniface_mask[i] & 0xff, b->fw.ip.iniface_mask[i] & 0xff, i); 1673384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1674384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1675384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if ((a->fw.ip.iniface[i] & a->fw.ip.iniface_mask[i]) 1676384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso != (b->fw.ip.iniface[i] & b->fw.ip.iniface_mask[i])) { 1677384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("different iniface\n"); 1678384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1679384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1680384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (a->fw.ip.outiface_mask[i] != b->fw.ip.outiface_mask[i]) { 1681384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("different outiface mask\n"); 1682384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1683384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1684384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if ((a->fw.ip.outiface[i] & a->fw.ip.outiface_mask[i]) 1685384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso != (b->fw.ip.outiface[i] & b->fw.ip.outiface_mask[i])) { 1686384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("different outiface\n"); 1687384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1688384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1689384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1690384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1691384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1692384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1693384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1694384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1695384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_parse_meta(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter, 1696384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct iptables_command_state *cs) 1697384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1698384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint8_t key = nft_rule_expr_get_u8(e, NFT_EXPR_META_KEY); 1699384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t value; 1700384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 1701384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const void *ifname; 1702384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 1703384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1704384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso e = nft_rule_expr_iter_next(iter); 1705384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (e == NULL) 1706384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1707384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1708384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name = nft_rule_expr_get_str(e, NFT_RULE_EXPR_ATTR_NAME); 1709384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "cmp") != 0) { 1710384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("skipping no cmp after meta\n"); 1711384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1712384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1713384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1714384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(key) { 1715384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_IIF: 1716384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso value = nft_rule_expr_get_u32(e, NFT_EXPR_CMP_DATA); 1717384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP) == NFT_CMP_NEQ) 1718384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.invflags |= IPT_INV_VIA_IN; 1719384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1720384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if_indextoname(value, cs->fw.ip.iniface); 1721384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1722384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memset(cs->fw.ip.iniface_mask, 0xff, 1723384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strlen(cs->fw.ip.iniface)+1); 1724384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1725384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_OIF: 1726384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso value = nft_rule_expr_get_u32(e, NFT_EXPR_CMP_DATA); 1727384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP) == NFT_CMP_NEQ) 1728384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.invflags |= IPT_INV_VIA_OUT; 1729384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1730384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if_indextoname(value, cs->fw.ip.outiface); 1731384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1732384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memset(cs->fw.ip.outiface_mask, 0xff, 1733384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strlen(cs->fw.ip.outiface)+1); 1734384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1735384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_IIFNAME: 1736384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname = nft_rule_expr_get(e, NFT_EXPR_CMP_DATA, &len); 1737384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP) == NFT_CMP_NEQ) 1738384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.invflags |= IPT_INV_VIA_IN; 1739384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1740384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(cs->fw.ip.iniface, ifname, len); 1741384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.iniface[len] = '\0'; 1742384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1743384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* If zero, then this is an interface mask */ 1744384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (if_nametoindex(cs->fw.ip.iniface) == 0) { 1745384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.iniface[len] = '+'; 1746384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.iniface[len+1] = '\0'; 1747384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1748384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1749384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memset(cs->fw.ip.iniface_mask, 0xff, len); 1750384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1751384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_OIFNAME: 1752384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname = nft_rule_expr_get(e, NFT_EXPR_CMP_DATA, &len); 1753384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP) == NFT_CMP_NEQ) 1754384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.invflags |= IPT_INV_VIA_OUT; 1755384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1756384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(cs->fw.ip.outiface, ifname, len); 1757384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.outiface[len] = '\0'; 1758384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1759384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* If zero, then this is an interface mask */ 1760384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (if_nametoindex(cs->fw.ip.outiface) == 0) { 1761384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.outiface[len] = '+'; 1762384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.outiface[len+1] = '\0'; 1763384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1764384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1765384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memset(cs->fw.ip.outiface_mask, 0xff, len); 1766384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1767384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso default: 1768384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("unknown meta key %d\n", key); 1769384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1770384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1771384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1772384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1773384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1774384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_parse_payload(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter, 1775384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct iptables_command_state *cs) 1776384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1777384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t offset; 1778384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool inv; 1779384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1780384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso offset = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_OFFSET); 1781384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1782384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(offset) { 1783384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct in_addr addr; 1784384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint8_t proto; 1785384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1786384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case offsetof(struct iphdr, saddr): 1787384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso get_cmp_data(iter, &addr, sizeof(addr), &inv); 1788384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.src.s_addr = addr.s_addr; 1789384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.smsk.s_addr = 0xffffffff; 1790384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (inv) 1791384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.invflags |= IPT_INV_SRCIP; 1792384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1793384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case offsetof(struct iphdr, daddr): 1794384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso get_cmp_data(iter, &addr, sizeof(addr), &inv); 1795384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.dst.s_addr = addr.s_addr; 1796384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.dmsk.s_addr = 0xffffffff; 1797384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (inv) 1798384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.invflags |= IPT_INV_DSTIP; 1799384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1800384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case offsetof(struct iphdr, protocol): 1801384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso get_cmp_data(iter, &proto, sizeof(proto), &inv); 1802384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.proto = proto; 1803384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (inv) 1804384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.invflags |= IPT_INV_PROTO; 1805384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1806384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso default: 1807384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("unknown payload offset %d\n", offset); 1808384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1809384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1810384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1811384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1812384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1813384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_parse_counter(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter, 1814384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_counters *counters) 1815384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1816384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->pcnt = nft_rule_expr_get_u64(e, NFT_EXPR_CTR_PACKETS); 1817384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->bcnt = nft_rule_expr_get_u64(e, NFT_EXPR_CTR_BYTES); 1818384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1819384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1820384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1821384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_parse_immediate(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter, 1822384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct iptables_command_state *cs) 1823384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1824384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int verdict = nft_rule_expr_get_u32(e, NFT_EXPR_IMM_VERDICT); 1825384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain = nft_rule_expr_get_str(e, NFT_EXPR_IMM_CHAIN); 1826384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1827384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Standard target? */ 1828384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(verdict) { 1829384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_ACCEPT: 1830384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->jumpto = "ACCEPT"; 1831384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1832384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_DROP: 1833384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->jumpto = "DROP"; 1834384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1835384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_RETURN: 1836384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->jumpto = "RETURN"; 1837384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1838384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_GOTO: 1839384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->fw.ip.flags |= IPT_F_GOTO; 1840384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_JUMP: 1841384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->jumpto = chain; 1842384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1843384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1844384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1845384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1846384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1847384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_rule_to_iptables_command_state(struct nft_rule *r, 1848384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct iptables_command_state *cs) 1849384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1850384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 1851384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 1852384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1853384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 1854384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) 1855384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1856384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1857384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1858384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 1859384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 1860384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 1861384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1862384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "counter") == 0) { 1863384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_parse_counter(expr, iter, &cs->counters); 1864384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "payload") == 0) { 1865384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_parse_payload(expr, iter, cs); 1866384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "meta") == 0) { 1867384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_parse_meta(expr, iter, cs); 1868384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "immediate") == 0) { 1869384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_parse_immediate(expr, iter, cs); 1870384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1871384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1872384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1873384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1874384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1875384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 1876384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1877384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1878384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int matches_howmany(struct xtables_rule_match *matches) 1879384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1880384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xtables_rule_match *matchp; 1881384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int matches_ctr = 0; 1882384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1883384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (matchp = matches; matchp; matchp = matchp->next) 1884384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso matches_ctr++; 1885384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1886384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return matches_ctr; 1887384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1888384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1889384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool 1890384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__find_match(struct nft_rule_expr *expr, struct xtables_rule_match *matches) 1891384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1892384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *matchname = nft_rule_expr_get_str(expr, NFT_EXPR_MT_NAME); 1893384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Netlink aligns this match info, don't trust this length variable */ 1894384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *data = nft_rule_expr_get_str(expr, NFT_EXPR_MT_INFO); 1895384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xtables_rule_match *matchp; 1896384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool found = false; 1897384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1898384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (matchp = matches; matchp; matchp = matchp->next) { 1899384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_entry_match *m = matchp->match->m; 1900384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1901384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(m->u.user.name, matchname) != 0) { 1902384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("mismatching match name\n"); 1903384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso continue; 1904384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1905384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1906384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (memcmp(data, m->data, m->u.user.match_size - sizeof(*m)) != 0) { 1907384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("mismatch match data\n"); 1908384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso continue; 1909384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1910384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso found = true; 1911384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1912384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1913384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1914384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return found; 1915384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1916384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1917384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool find_matches(struct xtables_rule_match *matches, struct nft_rule *r) 1918384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1919384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 1920384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 1921384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int kernel_matches = 0; 1922384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1923384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 1924384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 1925384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 1926384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1927384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1928384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1929384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1930384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 1931384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 1932384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 1933384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1934384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "match") == 0) { 1935384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!__find_match(expr, matches)) 1936384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1937384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1938384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso kernel_matches++; 1939384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1940384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1941384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1942384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 1943384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1944384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* same number of matches? */ 1945384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (matches_howmany(matches) != kernel_matches) 1946384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1947384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1948384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1949384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1950384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1951384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool __find_target(struct nft_rule_expr *expr, struct xt_entry_target *t) 1952384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1953384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 1954384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *tgname = nft_rule_expr_get_str(expr, NFT_EXPR_TG_NAME); 1955384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Netlink aligns this target info, don't trust this length variable */ 1956384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *data = nft_rule_expr_get(expr, NFT_EXPR_TG_INFO, &len); 1957384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1958384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(t->u.user.name, tgname) != 0) { 1959384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("mismatching target name\n"); 1960384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1961384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1962384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1963384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (memcmp(data, t->data, t->u.user.target_size - sizeof(*t)) != 0) 1964384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1965384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1966384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1967384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1968384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1969384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int targets_howmany(struct xtables_target *target) 1970384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1971384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return target != NULL ? 1 : 0; 1972384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1973384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1974384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool 1975384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusofind_target(struct xtables_target *target, struct nft_rule *r) 1976384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1977384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 1978384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 1979384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int kernel_targets = 0; 1980384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1981384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Special case: we use native immediate expressions to emulated 1982384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * standard targets. Also, we don't want to crash with no targets. 1983384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso */ 1984384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (target == NULL || strcmp(target->name, "standard") == 0) 1985384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1986384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1987384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 1988384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 1989384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 1990384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1991384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1992384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1993384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1994384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 1995384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 1996384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 1997384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1998384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "target") == 0) { 1999384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* we may support several targets in the future */ 2000384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!__find_target(expr, target->t)) 2001384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 2002384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2003384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso kernel_targets++; 2004384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2005384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2006384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2007384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 2008384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2009384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* same number of targets? */ 2010384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (targets_howmany(target) != kernel_targets) { 2011384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("kernel targets is %d but we passed %d\n", 2012384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso kernel_targets, targets_howmany(target)); 2013384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 2014384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2015384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2016384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 2017384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2018384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2019384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool 2020384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusofind_immediate(struct nft_rule *r, const char *jumpto) 2021384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2022384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 2023384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 2024384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2025384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 2026384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 2027384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 2028384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 2029384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2030384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2031384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2032384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 2033384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 2034384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 2035384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2036384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "immediate") == 0) { 2037384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int verdict = nft_rule_expr_get_u32(expr, NFT_EXPR_IMM_VERDICT); 2038384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *verdict_name = NULL; 2039384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2040384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* No target specified but immediate shows up, this 2041384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * is not the rule we are looking for. 2042384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso */ 2043384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strlen(jumpto) == 0) 2044384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 2045384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2046384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(verdict) { 2047384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_ACCEPT: 2048384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso verdict_name = "ACCEPT"; 2049384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2050384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_DROP: 2051384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso verdict_name = "DROP"; 2052384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2053384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_RETURN: 2054384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso verdict_name = "RETURN"; 2055384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2056384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2057384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2058384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Standard target? */ 2059384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (verdict_name && strcmp(jumpto, verdict_name) != 0) 2060384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 2061384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2062384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2063384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2064384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 2065384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2066384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 2067384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2068384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2069384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2070384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_rule_del(struct nft_handle *h, struct nft_rule *r) 2071384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2072384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 2073384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 2074384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 2075384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2076384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_DELRULE, AF_INET, 2077384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 2078384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_nlmsg_build_payload(nlh, r); 2079384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2080384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_print_debug(r, nlh); 2081384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2082384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 2083384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 2084384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_rule_del"); 2085384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2086384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2087384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 2088384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_rule_check(struct nft_handle *h, const char *chain, const char *table, 2089384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct iptables_command_state *cs, 2090384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool delete, int rulenum, bool verbose) 2091384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2092384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list; 2093384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list_iter *iter; 2094384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 2095384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 0; 2096384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rule_ctr = 0; 2097384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool found = false; 2098384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2099384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_get(h); 2100384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 2101384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot retrieve rule list from kernel\n"); 2102384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2103384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2104384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2105384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_list_iter_create(list); 2106384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 2107384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 2108384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2109384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2110384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2111384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 2112384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 2113384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 2114384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE); 2115384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_chain = 2116384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN); 2117384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct iptables_command_state this = {}; 2118384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2119384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0 || 2120384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcmp(chain, rule_chain) != 0) { 2121384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("different chain / table\n"); 2122384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2123384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2124384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2125384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (rulenum >= 0) { 2126384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Delete by rule number case */ 2127384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (rule_ctr != rulenum) { 2128384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso rule_ctr++; 2129384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2130384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2131384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2132384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Delete by matching rule case */ 2133384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("comparing with... "); 2134384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef DEBUG_DEL 2135384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_print_save(r, 0); 2136384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 2137384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2138384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_to_iptables_command_state(r, &this); 2139384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2140384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!is_same(cs, &this)) 2141384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2142384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2143384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!find_matches(cs->matches, r)) { 2144384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("matches not found\n"); 2145384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2146384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2147384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2148384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!find_target(cs->target, r)) { 2149384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("target not found\n"); 2150384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2151384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2152384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2153384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!find_immediate(r, cs->jumpto)) { 2154384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("immediate not found\n"); 2155384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2156384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2157384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2158384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso found = true; 2159384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2160384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2161384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2162384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 2163384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2164384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2165384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (found) { 2166384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 1; 2167384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2168384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (delete) { 2169384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("deleting rule\n"); 2170384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso __nft_rule_del(h, r); 2171384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2172384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2173384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2174384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_iter_destroy(iter); 2175384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_free(list); 2176384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2177384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == 0) 2178384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso errno = ENOENT; 2179384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2180384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 2181384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2182384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2183384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_check(struct nft_handle *h, const char *chain, 2184384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, struct iptables_command_state *e, 2185384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool verbose) 2186384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2187384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_check; 2188384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2189384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return __nft_rule_check(h, chain, table, e, false, -1, verbose); 2190384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2191384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2192384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_delete(struct nft_handle *h, const char *chain, 2193384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, struct iptables_command_state *e, 2194384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool verbose) 2195384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2196384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_delete; 2197384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2198384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return __nft_rule_check(h, chain, table, e, true, -1, verbose); 2199384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2200384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2201384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_delete_num(struct nft_handle *h, const char *chain, 2202384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, int rulenum, 2203384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool verbose) 2204384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2205384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_delete_num; 2206384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2207384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return __nft_rule_check(h, chain, table, NULL, true, rulenum, verbose); 2208384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2209384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2210384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_replace(struct nft_handle *h, const char *chain, 2211384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, struct iptables_command_state *cs, 2212384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rulenum, bool verbose) 2213384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2214384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 2215384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2216384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_replace; 2217384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2218384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = __nft_rule_check(h, chain, table, NULL, true, rulenum, verbose); 2219384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 2220384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 2221384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2222384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* XXX needs to be inserted in position, this is appending */ 2223384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return nft_rule_add(h, chain, table, cs, true, verbose); 2224384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2225384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2226384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* 2227384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * iptables print output emulation 2228384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso */ 2229384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2230384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT_NUMERIC 0x0001 2231384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT_NOCOUNTS 0x0002 2232384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT_KILOMEGAGIGA 0x0004 2233384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT_OPTIONS 0x0008 2234384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT_NOTABLE 0x0010 2235384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT_NOTARGET 0x0020 2236384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT_VIA 0x0040 2237384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT_NONEWLINE 0x0080 2238384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT_LINENUMBERS 0x0100 2239384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2240384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT_PRINT_RULE (FMT_NOCOUNTS | FMT_OPTIONS | FMT_VIA \ 2241384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso | FMT_NUMERIC | FMT_NOTABLE) 2242384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab)) 2243384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2244384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2245384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoprint_num(uint64_t number, unsigned int format) 2246384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2247384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_KILOMEGAGIGA) { 2248384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (number > 99999) { 2249384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso number = (number + 500) / 1000; 2250384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (number > 9999) { 2251384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso number = (number + 500) / 1000; 2252384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (number > 9999) { 2253384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso number = (number + 500) / 1000; 2254384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (number > 9999) { 2255384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso number = (number + 500) / 1000; 2256384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%4lluT ","%lluT "), (unsigned long long)number); 2257384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2258384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else printf(FMT("%4lluG ","%lluG "), (unsigned long long)number); 2259384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2260384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else printf(FMT("%4lluM ","%lluM "), (unsigned long long)number); 2261384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 2262384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%4lluK ","%lluK "), (unsigned long long)number); 2263384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 2264384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%5llu ","%llu "), (unsigned long long)number); 2265384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 2266384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%8llu ","%llu "), (unsigned long long)number); 2267384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2268384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2269384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2270384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoprint_header(unsigned int format, const char *chain, const char *pol, 2271384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_counters *counters, bool basechain, uint32_t refs) 2272384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2273384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("Chain %s", chain); 2274384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (basechain) { 2275384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(" (policy %s", pol); 2276384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOCOUNTS)) { 2277384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc(' ', stdout); 2278384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_num(counters->pcnt, (format|FMT_NOTABLE)); 2279384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs("packets, ", stdout); 2280384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_num(counters->bcnt, (format|FMT_NOTABLE)); 2281384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs("bytes", stdout); 2282384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2283384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(")\n"); 2284384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2285384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(" (%u references)\n", refs); 2286384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2287384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2288384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_LINENUMBERS) 2289384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-4s ", "%s "), "num"); 2290384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOCOUNTS)) { 2291384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_KILOMEGAGIGA) { 2292384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%5s ","%s "), "pkts"); 2293384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%5s ","%s "), "bytes"); 2294384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2295384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%8s ","%s "), "pkts"); 2296384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%10s ","%s "), "bytes"); 2297384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2298384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2299384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOTARGET)) 2300384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-9s ","%s "), "target"); 2301384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs(" prot ", stdout); 2302384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_OPTIONS) 2303384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs("opt", stdout); 2304384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_VIA) { 2305384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT(" %-6s ","%s "), "in"); 2306384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-6s ","%s "), "out"); 2307384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2308384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT(" %-19s ","%s "), "source"); 2309384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT(" %-19s "," %s "), "destination"); 2310384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("\n"); 2311384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2312384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2313384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2314384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoprint_match(struct nft_rule_expr *expr, int numeric) 2315384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2316384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 2317384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *match_name = nft_rule_expr_get_str(expr, NFT_EXPR_MT_NAME); 2318384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const void *match_info = nft_rule_expr_get(expr, NFT_EXPR_MT_INFO, &len); 2319384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xtables_match *match = 2320384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso xtables_find_match(match_name, XTF_TRY_LOAD, NULL); 2321384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_entry_match *m = 2322384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso calloc(1, sizeof(struct xt_entry_match) + len); 2323384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2324384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* emulate struct xt_entry_match since ->print needs it */ 2325384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy((void *)&m->data, match_info, len); 2326384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2327384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (match) { 2328384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (match->print) 2329384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* FIXME missing first parameter */ 2330384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso match->print(NULL, m, numeric); 2331384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 2332384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("%s ", match_name); 2333384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2334384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (match_name[0]) 2335384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("UNKNOWN match `%s' ", match_name); 2336384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2337384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2338384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso free(m); 2339384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2340384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2341384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2342384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoprint_firewall(const struct iptables_command_state *cs, struct nft_rule *r, 2343384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int num, unsigned int format) 2344384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2345384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xtables_target *target = NULL; 2346384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *targname = NULL; 2347384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const void *targinfo = NULL; 2348384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint8_t flags; 2349384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[BUFSIZ]; 2350384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 2351384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 2352384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_entry_target *t; 2353384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t target_len = 0; 2354384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2355384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 2356384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 2357384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 2358384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 2359384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2360384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2361384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2362384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 2363384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 2364384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 2365384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2366384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "target") == 0) { 2367384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso targname = nft_rule_expr_get_str(expr, NFT_EXPR_TG_NAME); 2368384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso targinfo = nft_rule_expr_get(expr, NFT_EXPR_TG_INFO, &target_len); 2369384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2370384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "immediate") == 0) { 2371384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t verdict = 2372384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_u32(expr, NFT_EXPR_IMM_VERDICT); 2373384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2374384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(verdict) { 2375384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_ACCEPT: 2376384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso targname = "ACCEPT"; 2377384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2378384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_DROP: 2379384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso targname = "DROP"; 2380384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2381384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_RETURN: 2382384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso targname = "RETURN"; 2383384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2384384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_GOTO: 2385384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso targname = nft_rule_expr_get_str(expr, NFT_EXPR_IMM_CHAIN); 2386384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2387384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_JUMP: 2388384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso targname = nft_rule_expr_get_str(expr, NFT_EXPR_IMM_CHAIN); 2389384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2390384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2391384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2392384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2393384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2394384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 2395384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2396384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso flags = cs->fw.ip.flags; 2397384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2398384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_LINENUMBERS) 2399384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-4u ", "%u "), num); 2400384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2401384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOCOUNTS)) { 2402384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_num(cs->counters.pcnt, format); 2403384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_num(cs->counters.bcnt, format); 2404384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2405384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2406384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOTARGET)) 2407384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-9s ", "%s "), targname ? targname : ""); 2408384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2409384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc(cs->fw.ip.invflags & XT_INV_PROTO ? '!' : ' ', stdout); 2410384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { 2411384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *pname = 2412384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso proto_to_name(cs->fw.ip.proto, format&FMT_NUMERIC); 2413384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (pname) 2414384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-5s", "%s "), pname); 2415384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 2416384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-5hu", "%hu "), cs->fw.ip.proto); 2417384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2418384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2419384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_OPTIONS) { 2420384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_NOTABLE) 2421384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs("opt ", stdout); 2422384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc(cs->fw.ip.invflags & IPT_INV_FRAG ? '!' : '-', stdout); 2423384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc(flags & IPT_F_FRAG ? 'f' : '-', stdout); 2424384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc(' ', stdout); 2425384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2426384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2427384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_VIA) { 2428384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char iface[IFNAMSIZ+2]; 2429384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.invflags & IPT_INV_VIA_IN) { 2430384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iface[0] = '!'; 2431384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iface[1] = '\0'; 2432384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2433384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else iface[0] = '\0'; 2434384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2435384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.iniface[0] != '\0') { 2436384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcat(iface, cs->fw.ip.iniface); 2437384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2438384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else if (format & FMT_NUMERIC) strcat(iface, "*"); 2439384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else strcat(iface, "any"); 2440384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT(" %-6s ","in %s "), iface); 2441384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2442384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.invflags & IPT_INV_VIA_OUT) { 2443384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iface[0] = '!'; 2444384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iface[1] = '\0'; 2445384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2446384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else iface[0] = '\0'; 2447384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2448384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.outiface[0] != '\0') { 2449384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcat(iface, cs->fw.ip.outiface); 2450384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2451384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else if (format & FMT_NUMERIC) strcat(iface, "*"); 2452384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else strcat(iface, "any"); 2453384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-6s ","out %s "), iface); 2454384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2455384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2456384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc(cs->fw.ip.invflags & IPT_INV_SRCIP ? '!' : ' ', stdout); 2457384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.smsk.s_addr == 0L && !(format & FMT_NUMERIC)) 2458384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-19s ","%s "), "anywhere"); 2459384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else { 2460384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_NUMERIC) 2461384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcpy(buf, xtables_ipaddr_to_numeric(&cs->fw.ip.src)); 2462384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 2463384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcpy(buf, xtables_ipaddr_to_anyname(&cs->fw.ip.src)); 2464384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcat(buf, xtables_ipmask_to_numeric(&cs->fw.ip.smsk)); 2465384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-19s ","%s "), buf); 2466384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2467384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2468384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc(cs->fw.ip.invflags & IPT_INV_DSTIP ? '!' : ' ', stdout); 2469384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->fw.ip.dmsk.s_addr == 0L && !(format & FMT_NUMERIC)) 2470384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-19s ","-> %s"), "anywhere"); 2471384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else { 2472384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_NUMERIC) 2473384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcpy(buf, xtables_ipaddr_to_numeric(&cs->fw.ip.dst)); 2474384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 2475384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcpy(buf, xtables_ipaddr_to_anyname(&cs->fw.ip.dst)); 2476384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcat(buf, xtables_ipmask_to_numeric(&cs->fw.ip.dmsk)); 2477384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-19s ","-> %s"), buf); 2478384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2479384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2480384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_NOTABLE) 2481384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs(" ", stdout); 2482384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2483384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef IPT_F_GOTO 2484384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if(cs->fw.ip.flags & IPT_F_GOTO) 2485384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("[goto] "); 2486384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 2487384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2488384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 2489384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 2490384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 2491384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 2492384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2493384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2494384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2495384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 2496384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 2497384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 2498384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2499384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "match") == 0) 2500384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_match(expr, format & FMT_NUMERIC); 2501384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2502384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2503384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2504384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 2505384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2506384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = calloc(1, sizeof(struct xt_entry_target) + target_len); 2507384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (t == NULL) 2508384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 2509384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2510384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* emulate struct xt_entry_match since ->print needs it */ 2511384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy((void *)&t->data, targinfo, target_len); 2512384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2513384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (targname) { 2514384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso target = xtables_find_target(targname, XTF_TRY_LOAD); 2515384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (target) { 2516384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (target->print) 2517384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* FIXME missing first parameter */ 2518384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso target->print(NULL, t, format & FMT_NUMERIC); 2519384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 2520384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("[%ld bytes of unknown target data] ", 2521384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso target_len); 2522384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2523384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso free(t); 2524384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2525384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NONEWLINE)) 2526384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc('\n', stdout); 2527384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2528384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2529384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 2530384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_rule_list(struct nft_handle *h, struct nft_chain *c, const char *table, 2531384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rulenum, unsigned int format, 2532384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void (*cb)(const struct iptables_command_state *cs, 2533384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r, unsigned int num, 2534384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int format)) 2535384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2536384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list; 2537384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list_iter *iter; 2538384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 2539384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rule_ctr = 0, ret = 0; 2540384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain = nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2541384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2542384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_get(h); 2543384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 2544384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot retrieve rule list from kernel\n"); 2545384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2546384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2547384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2548384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_list_iter_create(list); 2549384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 2550384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 2551384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2552384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2553384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2554384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 2555384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 2556384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 2557384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE); 2558384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_chain = 2559384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN); 2560384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2561384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso rule_ctr++; 2562384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2563384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0 || 2564384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcmp(chain, rule_chain) != 0) 2565384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2566384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2567384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (rulenum > 0) { 2568384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* List by rule number case */ 2569384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (rule_ctr != rulenum) { 2570384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso rule_ctr++; 2571384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2572384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2573384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2574384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct iptables_command_state cs = {}; 2575384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Show all rules case */ 2576384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_to_iptables_command_state(r, &cs); 2577384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2578384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cb(&cs, r, rule_ctr, format); 2579384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2580384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2581384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 2582384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2583384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2584384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_iter_destroy(iter); 2585384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_free(list); 2586384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2587384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == 0) 2588384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso errno = ENOENT; 2589384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2590384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 2591384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2592384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2593384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_list(struct nft_handle *h, const char *chain, const char *table, 2594384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rulenum, unsigned int format) 2595384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2596384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 2597384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 2598384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 2599384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2600384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_dump(h); 2601384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2602384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 2603384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 2604384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 2605384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2606384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2607384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2608384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2609384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2610384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2611384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 2612384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2613384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2614384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t policy = 2615384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY); 2616384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t refs = 2617384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_USE); 2618384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_counters ctrs = { 2619384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .pcnt = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS), 2620384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .bcnt = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES), 2621384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }; 2622384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool basechain = false; 2623384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2624384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM)) 2625384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso basechain = true; 2626384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2627384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 2628384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2629384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain && strcmp(chain, chain_name) != 0) 2630384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2631384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2632384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_header(format, chain_name, policy_name[policy], &ctrs, 2633384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso basechain, refs); 2634384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2635384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* this is a base chain */ 2636384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM)) { 2637384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso __nft_rule_list(h, c, table, rulenum, format, 2638384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_firewall); 2639384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2640384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2641384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2642384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2643384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2644384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 2645384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2646384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 2647384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2648384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2649384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2650384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusolist_save(const struct iptables_command_state *cs, struct nft_rule *r, 2651384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int num, unsigned int format) 2652384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2653384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_print_save(r, !(format & FMT_NOCOUNTS)); 2654384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2655384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2656384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 2657384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_rule_list_chain_save(struct nft_handle *h, const char *table, 2658384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list, int counters) 2659384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2660384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 2661384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 2662384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2663384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 2664384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 2665384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 2666384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2667384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2668384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2669384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2670384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2671384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2672384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 2673384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2674384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2675384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t policy = 2676384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY); 2677384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2678384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 2679384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2680384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2681384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* this is a base chain */ 2682384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM)) { 2683384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-P %s %s", chain_name, policy_name[policy]); 2684384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2685384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (counters) { 2686384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(" -c %lu %lu\n", 2687384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS), 2688384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES)); 2689384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 2690384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("\n"); 2691384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2692384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-N %s\n", chain_name); 2693384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2694384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2695384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2696384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2697384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2698384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 2699384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2700384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2701384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_list_save(struct nft_handle *h, const char *chain, 2702384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, int rulenum, int counters) 2703384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2704384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 2705384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 2706384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 2707384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2708384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_dump(h); 2709384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2710384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Dump policies and custom chains first */ 2711384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_chain_save(h, table, list, counters); 2712384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2713384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Now dump out rules in this table */ 2714384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 2715384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) { 2716384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("cannot allocate rule list iterator\n"); 2717384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2718384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2719384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2720384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2721384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2722384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2723384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 2724384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2725384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2726384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2727384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 2728384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2729384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain && strcmp(chain, chain_name) != 0) 2730384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2731384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2732384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso __nft_rule_list(h, c, table, rulenum, 2733384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters ? 0 : FMT_NOCOUNTS, list_save); 2734384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2735384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2736384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2737384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2738384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 2739384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2740384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 2741384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2742384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2743384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_compatible_revision(const char *name, uint8_t rev, int opt) 2744384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2745384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct mnl_socket *nl; 2746384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 2747384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 2748384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t portid, seq, type; 2749384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 0; 2750384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2751384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (opt == IPT_SO_GET_REVISION_MATCH) 2752384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso type = 0; 2753384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 2754384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso type = 1; 2755384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2756384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = mnl_nlmsg_put_header(buf); 2757384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_type = (NFNL_SUBSYS_NFT_COMPAT << 8) | NFNL_MSG_COMPAT_GET; 2758384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; 2759384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_seq = seq = time(NULL); 2760384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2761384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); 2762384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->nfgen_family = AF_INET; 2763384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->version = NFNETLINK_V0; 2764384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->res_id = 0; 2765384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2766384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_strz(nlh, NFTA_COMPAT_NAME, name); 2767384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_u32(nlh, NFTA_COMPAT_REV, htonl(rev)); 2768384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_u32(nlh, NFTA_COMPAT_TYPE, htonl(type)); 2769384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2770384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("requesting `%s' rev=%d type=%d via nft_compat\n", 2771384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name, rev, type); 2772384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2773384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nl = mnl_socket_open(NETLINK_NETFILTER); 2774384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nl == NULL) { 2775384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_open"); 2776384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2777384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2778384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2779384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { 2780384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_bind"); 2781384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2782384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2783384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso portid = mnl_socket_get_portid(nl); 2784384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2785384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { 2786384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_send"); 2787384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2788384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2789384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2790384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); 2791384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == -1) { 2792384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_recvfrom"); 2793384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2794384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2795384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2796384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL); 2797384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == -1) { 2798384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_cb_run"); 2799384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2800384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2801384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2802384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 2803384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_socket_close(nl); 2804384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2805384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret < 0 ? 0 : 1; 2806384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2807384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2808384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* Translates errno numbers into more human-readable form than strerror. */ 2809384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoconst char *nft_strerror(int err) 2810384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2811384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int i; 2812384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso static struct table_struct { 2813384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *fn; 2814384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int err; 2815384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *message; 2816384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } table[] = 2817384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { 2818384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, ENOTEMPTY, "Chain is not empty" }, 2819384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, EINVAL, "Can't delete built-in chain" }, 2820384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, EMLINK, 2821384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso "Can't delete chain with references left" }, 2822384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_add, EEXIST, "Chain already exists" }, 2823384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, E2BIG, "Index of insertion too big" }, 2824384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_replace, E2BIG, "Index of replacement too big" }, 2825384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_delete_num, E2BIG, "Index of deletion too big" }, 2826384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* { TC_READ_COUNTER, E2BIG, "Index of counter too big" }, 2827384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { TC_ZERO_COUNTER, E2BIG, "Index of counter too big" }, */ 2828384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, ELOOP, "Loop found in table" }, 2829384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, EINVAL, "Target problem" }, 2830384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* ENOENT for DELETE probably means no matching rule */ 2831384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_delete, ENOENT, 2832384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso "Bad rule (does a matching rule exist in that chain?)" }, 2833384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_set, ENOENT, "Bad built-in chain name" }, 2834384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_set, EINVAL, "Bad policy name" }, 2835384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, EPERM, "Permission denied (you must be root)" }, 2836384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, 0, "Incompatible with this kernel" }, 2837384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOPROTOOPT, "iptables who? (do you need to insmod?)" }, 2838384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOSYS, "Will be implemented real soon. I promise ;)" }, 2839384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOMEM, "Memory allocation problem" }, 2840384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOENT, "No chain/target/match by that name" }, 2841384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }; 2842384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2843384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) { 2844384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if ((!table[i].fn || table[i].fn == nft_fn) 2845384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso && table[i].err == err) 2846384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return table[i].message; 2847384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2848384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2849384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return strerror(err); 2850384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2851