4#include "internal/internal.h"
8#define CONNLABEL_CFG "/etc/xtables/connlabel.conf"
19 unsigned int namecount;
23static struct labelmap_bucket* label_map_bucket_alloc(
const char *n,
unsigned int b)
26 char *name = strdup(n);
31 bucket = malloc(
sizeof(*bucket));
41static unsigned int hash_name(
const char *name)
43 unsigned int hash = 0;
46 hash = (hash << 5) - hash + *name;
49 return hash & (HASH_SIZE - 1);
52int __labelmap_get_bit(
struct nfct_labelmap *m,
const char *name)
61 list = m->map_name[i];
64 if (strcmp(name, list->name) == 0)
71const char *__labelmap_get_name(
struct nfct_labelmap *m,
unsigned int bit)
73 if (bit < m->namecount)
74 return m->bit_to_name[bit] ? m->bit_to_name[bit] :
"";
78static int map_insert(
struct nfct_labelmap *m,
const char *n,
unsigned int b)
80 unsigned int i = hash_name(n);
84 if (strcmp(list->name, n) == 0)
89 list = label_map_bucket_alloc(n, b);
94 list->next = m->map_name[i];
97 m->map_name[i] = list;
101static int is_space_posix(
int c)
103 return c ==
' ' || c ==
'\f' || c ==
'\r' || c ==
'\t' || c ==
'\v';
106static char *trim_label(
char *label)
110 while (is_space_posix(*label))
112 end = strchr(label,
'\n');
116 end = strchr(label,
'\0');
119 while (end > label && is_space_posix(*end)) {
124 return *label ? label : NULL;
128xtables_parse_connlabel_numerical(
const char *s,
char **end)
132 value = strtoul(s, end, 0);
133 if (value == 0 && s == *end)
135 if (value >= MAX_BITS)
159 for (i = 0; i < HASH_SIZE; i++) {
160 b = map->map_name[i];
164 free(map->bit_to_name);
173 for (i = 0; i < HASH_SIZE; i++) {
176 m->bit_to_name[b->bit] = b->name;
187 for (i = 0; i < HASH_SIZE; i++)
188 map->map_name[i] = NULL;
189 map->bit_to_name = NULL;
202static bool label_is_sane(
const char *label)
204 for (;*label; label++) {
205 if (*label >=
'a' && *label <=
'z')
207 if (*label >=
'A' && *label <=
'Z')
209 if (*label >=
'0' && *label <=
'9')
211 if (*label ==
' ' || *label ==
'-')
218const char *__labels_get_path(
void)
220 return CONNLABEL_CFG;
230 unsigned int maxbit = 0;
231 uint32_t bits_seen[MAX_BITS/32];
233 fp = fopen(name ? name : CONNLABEL_CFG,
"re");
237 memset(bits_seen, 0,
sizeof(bits_seen));
245 while (fgets(label,
sizeof(label), fp)) {
251 bit = xtables_parse_connlabel_numerical(label, &end);
252 if (bit < 0 || test_bit(bit, bits_seen))
255 end = trim_label(end);
259 if (label_is_sane(end) && map_insert(map, end, bit) == 0) {
263 set_bit(bit, bits_seen);
270 map->namecount = maxbit + 1;
271 map->bit_to_name = calloc(
sizeof(
char *), map->namecount);
272 if (!map->bit_to_name)
274 make_name_table(map);
280 __labelmap_destroy(map);