libnftnl 1.2.6
gen.c
1/*
2 * (C) 2012-2014 by Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9#include "internal.h"
10
11#include <time.h>
12#include <endian.h>
13#include <stdint.h>
14#include <limits.h>
15#include <stdlib.h>
16#include <string.h>
17#include <netinet/in.h>
18#include <errno.h>
19
20#include <libmnl/libmnl.h>
21#include <linux/netfilter/nfnetlink.h>
22#include <linux/netfilter/nf_tables.h>
23
24#include <libnftnl/gen.h>
25
26struct nftnl_gen {
27 uint32_t id;
28
29 uint32_t flags;
30};
31
32EXPORT_SYMBOL(nftnl_gen_alloc);
33struct nftnl_gen *nftnl_gen_alloc(void)
34{
35 return calloc(1, sizeof(struct nftnl_gen));
36}
37
38EXPORT_SYMBOL(nftnl_gen_free);
39void nftnl_gen_free(const struct nftnl_gen *gen)
40{
41 xfree(gen);
42}
43
44EXPORT_SYMBOL(nftnl_gen_is_set);
45bool nftnl_gen_is_set(const struct nftnl_gen *gen, uint16_t attr)
46{
47 return gen->flags & (1 << attr);
48}
49
50EXPORT_SYMBOL(nftnl_gen_unset);
51void nftnl_gen_unset(struct nftnl_gen *gen, uint16_t attr)
52{
53 if (!(gen->flags & (1 << attr)))
54 return;
55
56 switch (attr) {
57 case NFTNL_GEN_ID:
58 break;
59 }
60 gen->flags &= ~(1 << attr);
61}
62
63static uint32_t nftnl_gen_validate[NFTNL_GEN_MAX + 1] = {
64 [NFTNL_GEN_ID] = sizeof(uint32_t),
65};
66
67EXPORT_SYMBOL(nftnl_gen_set_data);
68int nftnl_gen_set_data(struct nftnl_gen *gen, uint16_t attr,
69 const void *data, uint32_t data_len)
70{
71 nftnl_assert_attr_exists(attr, NFTNL_GEN_MAX);
72 nftnl_assert_validate(data, nftnl_gen_validate, attr, data_len);
73
74 switch (attr) {
75 case NFTNL_GEN_ID:
76 memcpy(&gen->id, data, sizeof(gen->id));
77 break;
78 }
79 gen->flags |= (1 << attr);
80 return 0;
81}
82
83int nftnl_gen_set(struct nftnl_gen *gen, uint16_t attr, const void *data) __visible;
84int nftnl_gen_set(struct nftnl_gen *gen, uint16_t attr, const void *data)
85{
86 return nftnl_gen_set_data(gen, attr, data, nftnl_gen_validate[attr]);
87}
88
89EXPORT_SYMBOL(nftnl_gen_set_u32);
90void nftnl_gen_set_u32(struct nftnl_gen *gen, uint16_t attr, uint32_t val)
91{
92 nftnl_gen_set_data(gen, attr, &val, sizeof(uint32_t));
93}
94
95EXPORT_SYMBOL(nftnl_gen_get_data);
96const void *nftnl_gen_get_data(const struct nftnl_gen *gen, uint16_t attr,
97 uint32_t *data_len)
98{
99 if (!(gen->flags & (1 << attr)))
100 return NULL;
101
102 switch(attr) {
103 case NFTNL_GEN_ID:
104 *data_len = sizeof(gen->id);
105 return &gen->id;
106 }
107 return NULL;
108}
109
110EXPORT_SYMBOL(nftnl_gen_get);
111const void *nftnl_gen_get(const struct nftnl_gen *gen, uint16_t attr)
112{
113 uint32_t data_len;
114 return nftnl_gen_get_data(gen, attr, &data_len);
115}
116
117EXPORT_SYMBOL(nftnl_gen_get_u32);
118uint32_t nftnl_gen_get_u32(const struct nftnl_gen *gen, uint16_t attr)
119{
120 const void *ret = nftnl_gen_get(gen, attr);
121 return ret == NULL ? 0 : *((uint32_t *)ret);
122}
123
124static int nftnl_gen_parse_attr_cb(const struct nlattr *attr, void *data)
125{
126 const struct nlattr **tb = data;
127 int type = mnl_attr_get_type(attr);
128
129 if (mnl_attr_type_valid(attr, NFTA_GEN_MAX) < 0)
130 return MNL_CB_OK;
131
132 switch(type) {
133 case NFTA_GEN_ID:
134 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
135 abi_breakage();
136 break;
137 }
138
139 tb[type] = attr;
140 return MNL_CB_OK;
141}
142
143EXPORT_SYMBOL(nftnl_gen_nlmsg_parse);
144int nftnl_gen_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_gen *gen)
145{
146 struct nlattr *tb[NFTA_GEN_MAX + 1] = {};
147
148 if (mnl_attr_parse(nlh, sizeof(struct nfgenmsg),
149 nftnl_gen_parse_attr_cb, tb) < 0)
150 return -1;
151
152 if (tb[NFTA_GEN_ID]) {
153 gen->id = ntohl(mnl_attr_get_u32(tb[NFTA_GEN_ID]));
154 gen->flags |= (1 << NFTNL_GEN_ID);
155 }
156 return 0;
157}
158
159static int nftnl_gen_cmd_snprintf(char *buf, size_t remain,
160 const struct nftnl_gen *gen, uint32_t cmd,
161 uint32_t type, uint32_t flags)
162{
163 int ret, offset = 0;
164
165 if (type != NFTNL_OUTPUT_DEFAULT)
166 return -1;
167
168 ret = snprintf(buf, remain, "ruleset generation ID %u", gen->id);
169 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
170 return offset;
171}
172
173EXPORT_SYMBOL(nftnl_gen_snprintf);
174int nftnl_gen_snprintf(char *buf, size_t size, const struct nftnl_gen *gen,
175 uint32_t type, uint32_t flags)
176{
177 if (size)
178 buf[0] = '\0';
179
180 return nftnl_gen_cmd_snprintf(buf, size, gen, nftnl_flag2cmd(flags), type,
181 flags);
182}
183
184static int nftnl_gen_do_snprintf(char *buf, size_t size, const void *gen,
185 uint32_t cmd, uint32_t type, uint32_t flags)
186{
187 return nftnl_gen_snprintf(buf, size, gen, type, flags);
188}
189
190EXPORT_SYMBOL(nftnl_gen_fprintf);
191int nftnl_gen_fprintf(FILE *fp, const struct nftnl_gen *gen, uint32_t type,
192 uint32_t flags)
193{
194 return nftnl_fprintf(fp, gen, NFTNL_CMD_UNSPEC, type, flags,
195 nftnl_gen_do_snprintf);
196}
Definition: gen.c:26