4 #include "internal/internal.h"
8 #define CONNLABEL_CFG "/etc/xtables/connlabel.conf"
19 unsigned int namecount;
23 static struct labelmap_bucket* label_map_bucket_alloc(
const char *n,
unsigned int b)
26 char *name = strdup(n);
31 bucket = malloc(
sizeof(*bucket));
41 static unsigned int hash_name(
const char *name)
43 unsigned int hash = 0;
46 hash = (hash << 5) - hash + *name;
49 return hash & (HASH_SIZE - 1);
52 int __labelmap_get_bit(
struct nfct_labelmap *m,
const char *name)
54 unsigned int i = hash_name(name);
58 if (strcmp(name, list->name) == 0)
65 const char *__labelmap_get_name(
struct nfct_labelmap *m,
unsigned int bit)
67 if (bit < m->namecount)
68 return m->bit_to_name[bit] ? m->bit_to_name[bit] :
"";
72 static int map_insert(
struct nfct_labelmap *m,
const char *n,
unsigned int b)
74 unsigned int i = hash_name(n);
78 if (strcmp(list->name, n) == 0)
83 list = label_map_bucket_alloc(n, b);
88 list->next = m->map_name[i];
91 m->map_name[i] = list;
95 static int is_space_posix(
int c)
97 return c ==
' ' || c ==
'\f' || c ==
'\r' || c ==
'\t' || c ==
'\v';
100 static char *trim_label(
char *label)
104 while (is_space_posix(*label))
106 end = strchr(label,
'\n');
110 end = strchr(label,
'\0');
113 while (end > label && is_space_posix(*end)) {
118 return *label ? label : NULL;
122 xtables_parse_connlabel_numerical(
const char *s,
char **end)
126 value = strtoul(s, end, 0);
127 if (value == 0 && s == *end)
129 if (value >= MAX_BITS)
153 for (i = 0; i < HASH_SIZE; i++) {
154 b = map->map_name[i];
158 free(map->bit_to_name);
167 for (i = 0; i < HASH_SIZE; i++) {
170 m->bit_to_name[b->bit] = b->name;
181 for (i = 0; i < HASH_SIZE; i++)
182 map->map_name[i] = NULL;
183 map->bit_to_name = NULL;
196 static bool label_is_sane(
const char *label)
198 for (;*label; label++) {
199 if (*label >=
'a' && *label <=
'z')
201 if (*label >=
'A' && *label <=
'Z')
203 if (*label >=
'0' && *label <=
'9')
205 if (*label ==
' ' || *label ==
'-')
212 const char *__labels_get_path(
void)
214 return CONNLABEL_CFG;
224 unsigned int maxbit = 0;
225 uint32_t bits_seen[MAX_BITS/32];
227 fp = fopen(name ? name : CONNLABEL_CFG,
"re");
231 memset(bits_seen, 0,
sizeof(bits_seen));
239 while (fgets(label,
sizeof(label), fp)) {
245 bit = xtables_parse_connlabel_numerical(label, &end);
246 if (bit < 0 || test_bit(bit, bits_seen))
249 end = trim_label(end);
253 if (label_is_sane(end) && map_insert(map, end, bit) == 0) {
257 set_bit(bit, bits_seen);
264 map->namecount = maxbit + 1;
265 map->bit_to_name = calloc(
sizeof(
char *), map->namecount);
266 if (!map->bit_to_name)
268 make_name_table(map);
274 __labelmap_destroy(map);