blob: e65219044eefef7f202ba0b708039172e601930d [file] [log] [blame]
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001/*
2 * Pattern management functions.
3 *
4 * Copyright 2000-2013 Willy Tarreau <w@1wt.eu>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <ctype.h>
14#include <stdio.h>
15
16#include <common/config.h>
17#include <common/standard.h>
18
19#include <types/global.h>
20#include <types/pattern.h>
21
22#include <proto/pattern.h>
Thierry FOURNIERe3ded592013-12-06 15:36:54 +010023#include <proto/sample.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010024
25#include <ebsttree.h>
26
Thierry FOURNIERa65b3432013-11-28 18:22:00 +010027char *pat_match_names[PAT_MATCH_NUM] = {
28 [PAT_MATCH_FOUND] = "found",
29 [PAT_MATCH_BOOL] = "bool",
30 [PAT_MATCH_INT] = "int",
31 [PAT_MATCH_IP] = "ip",
32 [PAT_MATCH_BIN] = "bin",
33 [PAT_MATCH_LEN] = "len",
34 [PAT_MATCH_STR] = "str",
35 [PAT_MATCH_BEG] = "beg",
36 [PAT_MATCH_SUB] = "sub",
37 [PAT_MATCH_DIR] = "dir",
38 [PAT_MATCH_DOM] = "dom",
39 [PAT_MATCH_END] = "end",
40 [PAT_MATCH_REG] = "reg",
Thierry FOURNIERed66c292013-11-28 11:05:19 +010041};
42
Thierry FOURNIER580c32c2014-01-24 10:58:12 +010043int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, enum pat_usage, char **) = {
Thierry FOURNIERa65b3432013-11-28 18:22:00 +010044 [PAT_MATCH_FOUND] = pat_parse_nothing,
45 [PAT_MATCH_BOOL] = pat_parse_nothing,
46 [PAT_MATCH_INT] = pat_parse_int,
47 [PAT_MATCH_IP] = pat_parse_ip,
48 [PAT_MATCH_BIN] = pat_parse_bin,
Thierry FOURNIERcc0e0b32013-12-06 16:56:40 +010049 [PAT_MATCH_LEN] = pat_parse_len,
Thierry FOURNIERa65b3432013-11-28 18:22:00 +010050 [PAT_MATCH_STR] = pat_parse_str,
51 [PAT_MATCH_BEG] = pat_parse_str,
52 [PAT_MATCH_SUB] = pat_parse_str,
53 [PAT_MATCH_DIR] = pat_parse_str,
54 [PAT_MATCH_DOM] = pat_parse_str,
55 [PAT_MATCH_END] = pat_parse_str,
56 [PAT_MATCH_REG] = pat_parse_reg,
Thierry FOURNIERed66c292013-11-28 11:05:19 +010057};
58
Thierry FOURNIERb9b08462013-12-13 15:12:32 +010059int (*pat_index_fcts[PAT_MATCH_NUM])(struct pattern_expr *, struct pattern *, char **) = {
60 [PAT_MATCH_FOUND] = pat_idx_list_val,
61 [PAT_MATCH_BOOL] = pat_idx_list_val,
62 [PAT_MATCH_INT] = pat_idx_list_val,
63 [PAT_MATCH_IP] = pat_idx_tree_ip,
64 [PAT_MATCH_BIN] = pat_idx_list_ptr,
65 [PAT_MATCH_LEN] = pat_idx_list_val,
66 [PAT_MATCH_STR] = pat_idx_tree_str,
67 [PAT_MATCH_BEG] = pat_idx_list_str,
68 [PAT_MATCH_SUB] = pat_idx_list_str,
69 [PAT_MATCH_DIR] = pat_idx_list_str,
70 [PAT_MATCH_DOM] = pat_idx_list_str,
71 [PAT_MATCH_END] = pat_idx_list_str,
72 [PAT_MATCH_REG] = pat_idx_list_reg,
73};
74
Willy Tarreau0cba6072013-11-28 22:21:02 +010075enum pat_match_res (*pat_match_fcts[PAT_MATCH_NUM])(struct sample *, struct pattern *) = {
Thierry FOURNIERa65b3432013-11-28 18:22:00 +010076 [PAT_MATCH_FOUND] = NULL,
77 [PAT_MATCH_BOOL] = pat_match_nothing,
78 [PAT_MATCH_INT] = pat_match_int,
79 [PAT_MATCH_IP] = pat_match_ip,
80 [PAT_MATCH_BIN] = pat_match_bin,
81 [PAT_MATCH_LEN] = pat_match_len,
82 [PAT_MATCH_STR] = pat_match_str,
83 [PAT_MATCH_BEG] = pat_match_beg,
84 [PAT_MATCH_SUB] = pat_match_sub,
85 [PAT_MATCH_DIR] = pat_match_dir,
86 [PAT_MATCH_DOM] = pat_match_dom,
87 [PAT_MATCH_END] = pat_match_end,
88 [PAT_MATCH_REG] = pat_match_reg,
Thierry FOURNIERed66c292013-11-28 11:05:19 +010089};
90
Thierry FOURNIERe3ded592013-12-06 15:36:54 +010091/* Just used for checking configuration compatibility */
92int pat_match_types[PAT_MATCH_NUM] = {
93 [PAT_MATCH_FOUND] = SMP_T_UINT,
94 [PAT_MATCH_BOOL] = SMP_T_UINT,
95 [PAT_MATCH_INT] = SMP_T_UINT,
96 [PAT_MATCH_IP] = SMP_T_ADDR,
97 [PAT_MATCH_BIN] = SMP_T_CBIN,
98 [PAT_MATCH_LEN] = SMP_T_CSTR,
99 [PAT_MATCH_STR] = SMP_T_CSTR,
100 [PAT_MATCH_BEG] = SMP_T_CSTR,
101 [PAT_MATCH_SUB] = SMP_T_CSTR,
102 [PAT_MATCH_DIR] = SMP_T_CSTR,
103 [PAT_MATCH_DOM] = SMP_T_CSTR,
104 [PAT_MATCH_END] = SMP_T_CSTR,
105 [PAT_MATCH_REG] = SMP_T_CSTR,
106};
107
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100108/*
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100109 *
110 * The following functions are not exported and are used by internals process
111 * of pattern matching
112 *
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100113 */
114
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100115/* Lookup an IPv4 address in the expression's pattern tree using the longest
116 * match method. The node is returned if it exists, otherwise NULL.
117 */
118static void *pat_lookup_ip(struct sample *smp, struct pattern_expr *expr)
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100119{
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100120 struct in_addr *s;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100121
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100122 if (smp->type != SMP_T_IPV4)
Thierry FOURNIERa65b3432013-11-28 18:22:00 +0100123 return PAT_NOMATCH;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100124
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100125 s = &smp->data.ipv4;
126 return ebmb_lookup_longest(&expr->pattern_tree, &s->s_addr);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100127}
128
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100129/* Free data allocated by pat_parse_reg */
130static void pat_free_reg(void *ptr)
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100131{
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100132 regex_free(ptr);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100133}
134
135/* Lookup a string in the expression's pattern tree. The node is returned if it
136 * exists, otherwise NULL.
137 */
Thierry FOURNIERa65b3432013-11-28 18:22:00 +0100138static void *pat_lookup_str(struct sample *smp, struct pattern_expr *expr)
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100139{
140 /* data are stored in a tree */
141 struct ebmb_node *node;
142 char prev;
143
144 /* we may have to force a trailing zero on the test pattern */
145 prev = smp->data.str.str[smp->data.str.len];
146 if (prev)
147 smp->data.str.str[smp->data.str.len] = '\0';
148 node = ebst_lookup(&expr->pattern_tree, smp->data.str.str);
149 if (prev)
150 smp->data.str.str[smp->data.str.len] = prev;
151 return node;
152}
153
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100154/* Background: Fast way to find a zero byte in a word
155 * http://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
156 * hasZeroByte = (v - 0x01010101UL) & ~v & 0x80808080UL;
157 *
158 * To look for 4 different byte values, xor the word with those bytes and
159 * then check for zero bytes:
160 *
161 * v = (((unsigned char)c * 0x1010101U) ^ delimiter)
162 * where <delimiter> is the 4 byte values to look for (as an uint)
163 * and <c> is the character that is being tested
164 */
165static inline unsigned int is_delimiter(unsigned char c, unsigned int mask)
166{
167 mask ^= (c * 0x01010101); /* propagate the char to all 4 bytes */
168 return (mask - 0x01010101) & ~mask & 0x80808080U;
169}
170
171static inline unsigned int make_4delim(unsigned char d1, unsigned char d2, unsigned char d3, unsigned char d4)
172{
173 return d1 << 24 | d2 << 16 | d3 << 8 | d4;
174}
175
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100176
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100177/*
178 *
179 * These functions are exported and may be used by any other component.
180 *
181 * The following functions are used for parsing pattern matching
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100182 * input value. The <text> contain the string to be parsed. <pattern>
183 * must be a preallocated pattern. The pat_parse_* functions fill this
184 * structure with the parsed value. <usage> can be PAT_U_COMPILE or
185 * PAT_U_LOOKUP. If the value PAT_U_COMPILE is used memory is allocated
186 * for filling the pattern. If the value PAT_U_LOOKUP is set, the parser
187 * use "trash" or return pointers to the input strings. In both cases,
188 * the caller must use the value PAT_U_LOOKUP with caution. <err> is
189 * filled with an error message built with memprintf() function.
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100190 *
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100191 * In succes case, the pat_parse_* function return 1. If the function
192 * fail, it returns 0 and <err> is filled.
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100193 *
194 */
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100195
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100196/* ignore the current line */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100197int pat_parse_nothing(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100198{
199 return 1;
200}
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100201
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100202/* Parse a string. It is allocated and duplicated. */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100203int pat_parse_str(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100204{
205 pattern->type = SMP_T_CSTR;
206 pattern->expect_type = SMP_T_CSTR;
207 if (usage == PAT_U_COMPILE) {
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100208 pattern->ptr.str = strdup(text);
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100209 if (!pattern->ptr.str) {
210 memprintf(err, "out of memory while loading string pattern");
211 return 0;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100212 }
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100213 }
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100214 else
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100215 pattern->ptr.str = (char *)text;
216 pattern->len = strlen(text);
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100217 return 1;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100218}
219
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100220/* Parse a binary written in hexa. It is allocated. */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100221int pat_parse_bin(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100222{
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100223 struct chunk *trash;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100224
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100225 pattern->type = SMP_T_CBIN;
226 pattern->expect_type = SMP_T_CBIN;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100227
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100228 if (usage == PAT_U_COMPILE)
229 /* If the parse_binary fails, it returns 0. In succes case, it returns
230 * the length of the arsed binary content. The functions pat_parse_*
231 * must return 0 if fail and the number of elements eated from **text
232 * if not fail. In succes case, this function eat always 1 elements.
233 * The double operator "!" converts the range "1-n" to "1".
234 */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100235 return !!parse_binary(text, &pattern->ptr.str, &pattern->len, err);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100236
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100237 trash = get_trash_chunk();
238 pattern->len = trash->size;
239 pattern->ptr.str = trash->str;
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100240 return !!parse_binary(text, &pattern->ptr.str, &pattern->len, err);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100241}
242
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100243/* Parse a regex. It is allocated. */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100244int pat_parse_reg(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100245{
Thierry FOURNIER799c0422013-12-06 20:36:20 +0100246 struct my_regex *preg;
Thierry FOURNIER0b2fe4a2013-12-06 20:33:50 +0100247 struct chunk *trash;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100248
Thierry FOURNIER0b2fe4a2013-12-06 20:33:50 +0100249 if (usage == PAT_U_COMPILE) {
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100250
Thierry FOURNIER0b2fe4a2013-12-06 20:33:50 +0100251 preg = calloc(1, sizeof(*preg));
252 if (!preg) {
253 memprintf(err, "out of memory while loading pattern");
254 return 0;
255 }
256
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100257 if (!regex_comp(text, preg, !(pattern->flags & PAT_F_IGNORE_CASE), 0, err)) {
Thierry FOURNIER0b2fe4a2013-12-06 20:33:50 +0100258 free(preg);
259 return 0;
260 }
261 pattern->freeptrbuf = &pat_free_reg;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100262 }
Thierry FOURNIER0b2fe4a2013-12-06 20:33:50 +0100263 else {
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100264
Thierry FOURNIER0b2fe4a2013-12-06 20:33:50 +0100265 trash = get_trash_chunk();
266 if (trash->size < sizeof(*preg)) {
267 memprintf(err, "no space avalaible in the buffer. expect %d, provides %d",
268 (int)sizeof(*preg), trash->size);
269 return 0;
270 }
271
272 preg = (struct my_regex *)trash->str;
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100273 preg->regstr = (char *)text;
Thierry FOURNIER0b2fe4a2013-12-06 20:33:50 +0100274 pattern->freeptrbuf = NULL;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100275 }
276
277 pattern->ptr.reg = preg;
Thierry FOURNIERcc0e0b32013-12-06 16:56:40 +0100278 pattern->expect_type = SMP_T_CSTR;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100279 return 1;
280}
281
282/* Parse a range of positive integers delimited by either ':' or '-'. If only
283 * one integer is read, it is set as both min and max. An operator may be
284 * specified as the prefix, among this list of 5 :
285 *
286 * 0:eq, 1:gt, 2:ge, 3:lt, 4:le
287 *
288 * The default operator is "eq". It supports range matching. Ranges are
289 * rejected for other operators. The operator may be changed at any time.
290 * The operator is stored in the 'opaque' argument.
291 *
292 * If err is non-NULL, an error message will be returned there on errors and
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100293 * the caller will have to free it. The function returns zero on error, and
294 * non-zero on success.
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100295 *
296 */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100297int pat_parse_int(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100298{
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100299 const char *ptr = text;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100300
301 pattern->type = SMP_T_UINT;
Thierry FOURNIERcc0e0b32013-12-06 16:56:40 +0100302 pattern->expect_type = SMP_T_UINT;
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100303
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100304 /* Empty string is not valid */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100305 if (!*text)
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100306 goto not_valid_range;
307
308 /* Search ':' or '-' separator. */
309 while (*ptr != '\0' && *ptr != ':' && *ptr != '-')
310 ptr++;
311
312 /* If separator not found. */
313 if (!*ptr) {
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100314 if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0) {
315 memprintf(err, "'%s' is not a number", text);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100316 return 0;
317 }
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100318 pattern->val.range.max = pattern->val.range.min;
319 pattern->val.range.min_set = 1;
320 pattern->val.range.max_set = 1;
321 return 1;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100322 }
323
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100324 /* If the separator is the first character. */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100325 if (ptr == text && *(ptr + 1) != '\0') {
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100326 if (strl2llrc(ptr + 1, strlen(ptr + 1), &pattern->val.range.max) != 0)
327 goto not_valid_range;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100328
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100329 pattern->val.range.min_set = 0;
330 pattern->val.range.max_set = 1;
331 return 1;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100332 }
333
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100334 /* If separator is the last character. */
335 if (*(ptr + 1) == '\0') {
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100336 if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0)
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100337 goto not_valid_range;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100338
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100339 pattern->val.range.min_set = 1;
340 pattern->val.range.max_set = 0;
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100341 return 1;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100342 }
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100343
344 /* Else, parse two numbers. */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100345 if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0)
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100346 goto not_valid_range;
347
348 if (strl2llrc(ptr + 1, strlen(ptr + 1), &pattern->val.range.max) != 0)
349 goto not_valid_range;
350
351 if (pattern->val.range.min > pattern->val.range.max)
352 goto not_valid_range;
353
354 pattern->val.range.min_set = 1;
355 pattern->val.range.max_set = 1;
356 return 1;
357
358 not_valid_range:
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100359 memprintf(err, "'%s' is not a valid number range", text);
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100360 return 0;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100361}
362
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100363int pat_parse_len(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
Thierry FOURNIERcc0e0b32013-12-06 16:56:40 +0100364{
365 int ret;
366
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100367 ret = pat_parse_int(text, pattern, usage, err);
Thierry FOURNIERcc0e0b32013-12-06 16:56:40 +0100368 pattern->expect_type = SMP_T_CSTR;
369 return ret;
370}
371
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100372/* Parse a range of positive 2-component versions delimited by either ':' or
373 * '-'. The version consists in a major and a minor, both of which must be
374 * smaller than 65536, because internally they will be represented as a 32-bit
375 * integer.
376 * If only one version is read, it is set as both min and max. Just like for
377 * pure integers, an operator may be specified as the prefix, among this list
378 * of 5 :
379 *
380 * 0:eq, 1:gt, 2:ge, 3:lt, 4:le
381 *
382 * The default operator is "eq". It supports range matching. Ranges are
383 * rejected for other operators. The operator may be changed at any time.
384 * The operator is stored in the 'opaque' argument. This allows constructs
385 * such as the following one :
386 *
387 * acl obsolete_ssl ssl_req_proto lt 3
388 * acl unsupported_ssl ssl_req_proto gt 3.1
389 * acl valid_ssl ssl_req_proto 3.0-3.1
390 *
391 */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100392int pat_parse_dotted_ver(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100393{
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100394 const char *ptr = text;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100395
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100396 pattern->type = SMP_T_UINT;
397 pattern->expect_type = SMP_T_UINT;
398
399 /* Search ':' or '-' separator. */
400 while (*ptr != '\0' && *ptr != ':' && *ptr != '-')
401 ptr++;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100402
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100403 /* If separator not found. */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100404 if (*ptr == '\0' && ptr > text) {
405 if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
406 memprintf(err, "'%s' is not a dotted number", text);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100407 return 0;
408 }
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100409 pattern->val.range.max = pattern->val.range.min;
410 pattern->val.range.min_set = 1;
411 pattern->val.range.max_set = 1;
412 return 1;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100413 }
414
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100415 /* If the separator is the first character. */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100416 if (ptr == text && *(ptr+1) != '\0') {
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100417 if (strl2llrc_dotted(ptr+1, strlen(ptr+1), &pattern->val.range.max) != 0) {
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100418 memprintf(err, "'%s' is not a valid dotted number range", text);
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100419 return 0;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100420 }
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100421 pattern->val.range.min_set = 0;
422 pattern->val.range.max_set = 1;
423 return 1;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100424 }
425
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100426 /* If separator is the last character. */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100427 if (ptr == &text[strlen(text)-1]) {
428 if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
429 memprintf(err, "'%s' is not a valid dotted number range", text);
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100430 return 0;
431 }
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100432 pattern->val.range.min_set = 1;
433 pattern->val.range.max_set = 0;
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100434 return 1;
435 }
436
437 /* Else, parse two numbers. */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100438 if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
439 memprintf(err, "'%s' is not a valid dotted number range", text);
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100440 return 0;
441 }
442 if (strl2llrc_dotted(ptr+1, strlen(ptr+1), &pattern->val.range.max) != 0) {
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100443 memprintf(err, "'%s' is not a valid dotted number range", text);
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100444 return 0;
445 }
446 if (pattern->val.range.min > pattern->val.range.max) {
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100447 memprintf(err, "'%s' is not a valid dotted number range", text);
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100448 return 0;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100449 }
Thierry FOURNIER511e9472014-01-23 17:40:34 +0100450 pattern->val.range.min_set = 1;
451 pattern->val.range.max_set = 1;
452 return 1;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100453}
454
455/* Parse an IP address and an optional mask in the form addr[/mask].
456 * The addr may either be an IPv4 address or a hostname. The mask
457 * may either be a dotted mask or a number of bits. Returns 1 if OK,
458 * otherwise 0. NOTE: IP address patterns are typed (IPV4/IPV6).
459 */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100460int pat_parse_ip(const char *text, struct pattern *pattern, enum pat_usage usage, char **err)
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100461{
Thierry FOURNIERcc0e0b32013-12-06 16:56:40 +0100462 pattern->expect_type = SMP_T_ADDR;
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100463 if (str2net(text, &pattern->val.ipv4.addr, &pattern->val.ipv4.mask)) {
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100464 pattern->type = SMP_T_IPV4;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100465 return 1;
466 }
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100467 else if (str62net(text, &pattern->val.ipv6.addr, &pattern->val.ipv6.mask)) {
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100468 /* no tree support right now */
469 pattern->type = SMP_T_IPV6;
470 return 1;
471 }
472 else {
Thierry FOURNIER580c32c2014-01-24 10:58:12 +0100473 memprintf(err, "'%s' is not a valid IPv4 or IPv6 address", text);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100474 return 0;
475 }
476}
477
Thierry FOURNIERe7ba2362014-01-21 11:25:41 +0100478/*
479 *
480 * These functions are exported and may be used by any other component.
481 *
482 * This fucntion just take a sample <smp> and check if this sample match
483 * with the pattern <pattern>. This fucntion return just PAT_MATCH or
484 * PAT_NOMATCH.
485 *
486 */
487
488/* always return false */
489enum pat_match_res pat_match_nothing(struct sample *smp, struct pattern *pattern)
490{
491 return PAT_NOMATCH;
492}
493
494
495/* NB: For two strings to be identical, it is required that their lengths match */
496enum pat_match_res pat_match_str(struct sample *smp, struct pattern *pattern)
497{
498 int icase;
499
500 if (pattern->len != smp->data.str.len)
501 return PAT_NOMATCH;
502
503 icase = pattern->flags & PAT_F_IGNORE_CASE;
504 if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0) ||
505 (!icase && strncmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0))
506 return PAT_MATCH;
507 return PAT_NOMATCH;
508}
509
510/* NB: For two binaries buf to be identical, it is required that their lengths match */
511enum pat_match_res pat_match_bin(struct sample *smp, struct pattern *pattern)
512{
513 if (pattern->len != smp->data.str.len)
514 return PAT_NOMATCH;
515
516 if (memcmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0)
517 return PAT_MATCH;
518 return PAT_NOMATCH;
519}
520
521/* Executes a regex. It temporarily changes the data to add a trailing zero,
522 * and restores the previous character when leaving.
523 */
524enum pat_match_res pat_match_reg(struct sample *smp, struct pattern *pattern)
525{
526 if (regex_exec(pattern->ptr.reg, smp->data.str.str, smp->data.str.len) == 0)
527 return PAT_MATCH;
528 return PAT_NOMATCH;
529}
530
531/* Checks that the pattern matches the beginning of the tested string. */
532enum pat_match_res pat_match_beg(struct sample *smp, struct pattern *pattern)
533{
534 int icase;
535
536 if (pattern->len > smp->data.str.len)
537 return PAT_NOMATCH;
538
539 icase = pattern->flags & PAT_F_IGNORE_CASE;
540 if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str, pattern->len) != 0) ||
541 (!icase && strncmp(pattern->ptr.str, smp->data.str.str, pattern->len) != 0))
542 return PAT_NOMATCH;
543 return PAT_MATCH;
544}
545
546/* Checks that the pattern matches the end of the tested string. */
547enum pat_match_res pat_match_end(struct sample *smp, struct pattern *pattern)
548{
549 int icase;
550
551 if (pattern->len > smp->data.str.len)
552 return PAT_NOMATCH;
553 icase = pattern->flags & PAT_F_IGNORE_CASE;
554 if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str + smp->data.str.len - pattern->len, pattern->len) != 0) ||
555 (!icase && strncmp(pattern->ptr.str, smp->data.str.str + smp->data.str.len - pattern->len, pattern->len) != 0))
556 return PAT_NOMATCH;
557 return PAT_MATCH;
558}
559
560/* Checks that the pattern is included inside the tested string.
561 * NB: Suboptimal, should be rewritten using a Boyer-Moore method.
562 */
563enum pat_match_res pat_match_sub(struct sample *smp, struct pattern *pattern)
564{
565 int icase;
566 char *end;
567 char *c;
568
569 if (pattern->len > smp->data.str.len)
570 return PAT_NOMATCH;
571
572 end = smp->data.str.str + smp->data.str.len - pattern->len;
573 icase = pattern->flags & PAT_F_IGNORE_CASE;
574 if (icase) {
575 for (c = smp->data.str.str; c <= end; c++) {
576 if (tolower(*c) != tolower(*pattern->ptr.str))
577 continue;
578 if (strncasecmp(pattern->ptr.str, c, pattern->len) == 0)
579 return PAT_MATCH;
580 }
581 } else {
582 for (c = smp->data.str.str; c <= end; c++) {
583 if (*c != *pattern->ptr.str)
584 continue;
585 if (strncmp(pattern->ptr.str, c, pattern->len) == 0)
586 return PAT_MATCH;
587 }
588 }
589 return PAT_NOMATCH;
590}
591
592/* This one is used by other real functions. It checks that the pattern is
593 * included inside the tested string, but enclosed between the specified
594 * delimiters or at the beginning or end of the string. The delimiters are
595 * provided as an unsigned int made by make_4delim() and match up to 4 different
596 * delimiters. Delimiters are stripped at the beginning and end of the pattern.
597 */
598static int match_word(struct sample *smp, struct pattern *pattern, unsigned int delimiters)
599{
600 int may_match, icase;
601 char *c, *end;
602 char *ps;
603 int pl;
604
605 pl = pattern->len;
606 ps = pattern->ptr.str;
607
608 while (pl > 0 && is_delimiter(*ps, delimiters)) {
609 pl--;
610 ps++;
611 }
612
613 while (pl > 0 && is_delimiter(ps[pl - 1], delimiters))
614 pl--;
615
616 if (pl > smp->data.str.len)
617 return PAT_NOMATCH;
618
619 may_match = 1;
620 icase = pattern->flags & PAT_F_IGNORE_CASE;
621 end = smp->data.str.str + smp->data.str.len - pl;
622 for (c = smp->data.str.str; c <= end; c++) {
623 if (is_delimiter(*c, delimiters)) {
624 may_match = 1;
625 continue;
626 }
627
628 if (!may_match)
629 continue;
630
631 if (icase) {
632 if ((tolower(*c) == tolower(*ps)) &&
633 (strncasecmp(ps, c, pl) == 0) &&
634 (c == end || is_delimiter(c[pl], delimiters)))
635 return PAT_MATCH;
636 } else {
637 if ((*c == *ps) &&
638 (strncmp(ps, c, pl) == 0) &&
639 (c == end || is_delimiter(c[pl], delimiters)))
640 return PAT_MATCH;
641 }
642 may_match = 0;
643 }
644 return PAT_NOMATCH;
645}
646
647/* Checks that the pattern is included inside the tested string, but enclosed
648 * between the delimiters '?' or '/' or at the beginning or end of the string.
649 * Delimiters at the beginning or end of the pattern are ignored.
650 */
651enum pat_match_res pat_match_dir(struct sample *smp, struct pattern *pattern)
652{
653 return match_word(smp, pattern, make_4delim('/', '?', '?', '?'));
654}
655
656/* Checks that the pattern is included inside the tested string, but enclosed
657 * between the delmiters '/', '?', '.' or ":" or at the beginning or end of
658 * the string. Delimiters at the beginning or end of the pattern are ignored.
659 */
660enum pat_match_res pat_match_dom(struct sample *smp, struct pattern *pattern)
661{
662 return match_word(smp, pattern, make_4delim('/', '?', '.', ':'));
663}
664
665/* Checks that the integer in <test> is included between min and max */
666enum pat_match_res pat_match_int(struct sample *smp, struct pattern *pattern)
667{
668 if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.uint) &&
669 (!pattern->val.range.max_set || smp->data.uint <= pattern->val.range.max))
670 return PAT_MATCH;
671 return PAT_NOMATCH;
672}
673
674/* Checks that the length of the pattern in <test> is included between min and max */
675enum pat_match_res pat_match_len(struct sample *smp, struct pattern *pattern)
676{
677 if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.str.len) &&
678 (!pattern->val.range.max_set || smp->data.str.len <= pattern->val.range.max))
679 return PAT_MATCH;
680 return PAT_NOMATCH;
681}
682
683enum pat_match_res pat_match_ip(struct sample *smp, struct pattern *pattern)
684{
685 unsigned int v4; /* in network byte order */
686 struct in6_addr *v6;
687 int bits, pos;
688 struct in6_addr tmp6;
689
690 if (pattern->type == SMP_T_IPV4) {
691 if (smp->type == SMP_T_IPV4) {
692 v4 = smp->data.ipv4.s_addr;
693 }
694 else if (smp->type == SMP_T_IPV6) {
695 /* v4 match on a V6 sample. We want to check at least for
696 * the following forms :
697 * - ::ffff:ip:v4 (ipv4 mapped)
698 * - ::0000:ip:v4 (old ipv4 mapped)
699 * - 2002:ip:v4:: (6to4)
700 */
701 if (*(uint32_t*)&smp->data.ipv6.s6_addr[0] == 0 &&
702 *(uint32_t*)&smp->data.ipv6.s6_addr[4] == 0 &&
703 (*(uint32_t*)&smp->data.ipv6.s6_addr[8] == 0 ||
704 *(uint32_t*)&smp->data.ipv6.s6_addr[8] == htonl(0xFFFF))) {
705 v4 = *(uint32_t*)&smp->data.ipv6.s6_addr[12];
706 }
707 else if (*(uint16_t*)&smp->data.ipv6.s6_addr[0] == htons(0x2002)) {
708 v4 = htonl((ntohs(*(uint16_t*)&smp->data.ipv6.s6_addr[2]) << 16) +
709 ntohs(*(uint16_t*)&smp->data.ipv6.s6_addr[4]));
710 }
711 else
712 return PAT_NOMATCH;
713 }
714 else
715 return PAT_NOMATCH;
716
717 if (((v4 ^ pattern->val.ipv4.addr.s_addr) & pattern->val.ipv4.mask.s_addr) == 0)
718 return PAT_MATCH;
719 else
720 return PAT_NOMATCH;
721 }
722 else if (pattern->type == SMP_T_IPV6) {
723 if (smp->type == SMP_T_IPV4) {
724 /* Convert the IPv4 sample address to IPv4 with the
725 * mapping method using the ::ffff: prefix.
726 */
727 memset(&tmp6, 0, 10);
728 *(uint16_t*)&tmp6.s6_addr[10] = htons(0xffff);
729 *(uint32_t*)&tmp6.s6_addr[12] = smp->data.ipv4.s_addr;
730 v6 = &tmp6;
731 }
732 else if (smp->type == SMP_T_IPV6) {
733 v6 = &smp->data.ipv6;
734 }
735 else {
736 return PAT_NOMATCH;
737 }
738
739 bits = pattern->val.ipv6.mask;
740 for (pos = 0; bits > 0; pos += 4, bits -= 32) {
741 v4 = *(uint32_t*)&v6->s6_addr[pos] ^ *(uint32_t*)&pattern->val.ipv6.addr.s6_addr[pos];
742 if (bits < 32)
743 v4 &= htonl((~0U) << (32-bits));
744 if (v4)
745 return PAT_NOMATCH;
746 }
747 return PAT_MATCH;
748 }
749 return PAT_NOMATCH;
750}
751
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100752/* NB: does nothing if <pat> is NULL */
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +0100753void pattern_free(struct pattern_list *pat)
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100754{
755 if (!pat)
756 return;
757
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +0100758 if (pat->pat.ptr.ptr) {
759 if (pat->pat.freeptrbuf)
760 pat->pat.freeptrbuf(pat->pat.ptr.ptr);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100761
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +0100762 free(pat->pat.ptr.ptr);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100763 }
764
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +0100765 free(pat->pat.smp);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100766 free(pat);
767}
768
769void free_pattern_list(struct list *head)
770{
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +0100771 struct pattern_list *pat, *tmp;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100772 list_for_each_entry_safe(pat, tmp, head, list)
Thierry FOURNIERa65b3432013-11-28 18:22:00 +0100773 pattern_free(pat);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100774}
775
776void free_pattern_tree(struct eb_root *root)
777{
778 struct eb_node *node, *next;
Thierry FOURNIER3ce88c72013-12-09 11:29:46 +0100779 struct pat_idx_elt *elt;
780
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100781 node = eb_first(root);
782 while (node) {
783 next = eb_next(node);
784 eb_delete(node);
Thierry FOURNIER3ce88c72013-12-09 11:29:46 +0100785 elt = container_of(node, struct pat_idx_elt, node);
Thierry FOURNIERc64de3f2013-12-10 15:08:39 +0100786 free(elt->smp);
Thierry FOURNIER3ce88c72013-12-09 11:29:46 +0100787 free(elt);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100788 node = next;
789 }
790}
791
Thierry FOURNIERa65b3432013-11-28 18:22:00 +0100792void pattern_prune_expr(struct pattern_expr *expr)
Thierry FOURNIERd163e1c2013-11-28 11:41:23 +0100793{
794 free_pattern_list(&expr->patterns);
795 free_pattern_tree(&expr->pattern_tree);
796 LIST_INIT(&expr->patterns);
797}
798
Thierry FOURNIERa65b3432013-11-28 18:22:00 +0100799void pattern_init_expr(struct pattern_expr *expr)
Thierry FOURNIERd163e1c2013-11-28 11:41:23 +0100800{
801 LIST_INIT(&expr->patterns);
802 expr->pattern_tree = EB_ROOT_UNIQUE;
803}
804
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100805/*
806 *
807 * The following functions are used for the pattern indexation
808 *
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100809 */
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100810
811int pat_idx_list_val(struct pattern_expr *expr, struct pattern *pat, char **err)
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100812{
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100813 struct pattern_list *patl;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100814
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100815 /* allocate pattern */
816 patl = calloc(1, sizeof(*patl));
817 if (!patl) {
818 memprintf(err, "out of memory while indexing pattern");
Thierry FOURNIER972028f2014-01-23 17:53:31 +0100819 return 0;
820 }
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100821
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100822 /* duplicate pattern */
823 memcpy(&patl->pat, pat, sizeof(*pat));
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100824
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100825 /* chain pattern in the expression */
826 LIST_ADDQ(&expr->patterns, &patl->list);
827
828 /* that's ok */
829 return 1;
830}
831
832int pat_idx_list_ptr(struct pattern_expr *expr, struct pattern *pat, char **err)
833{
834 struct pattern_list *patl;
835
836 /* allocate pattern */
837 patl = calloc(1, sizeof(*patl));
838 if (!patl)
Thierry FOURNIER972028f2014-01-23 17:53:31 +0100839 return 0;
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100840
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100841 /* duplicate pattern */
842 memcpy(&patl->pat, pat, sizeof(*pat));
843 patl->pat.ptr.ptr = malloc(patl->pat.len);
844 if (!patl->pat.ptr.ptr) {
845 free(patl);
846 memprintf(err, "out of memory while indexing pattern");
847 return 0;
848 }
849 memcpy(patl->pat.ptr.ptr, pat->ptr.ptr, pat->len);
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100850
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100851 /* chain pattern in the expression */
852 LIST_ADDQ(&expr->patterns, &patl->list);
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100853
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100854 /* that's ok */
855 return 1;
856}
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100857
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100858int pat_idx_list_str(struct pattern_expr *expr, struct pattern *pat, char **err)
859{
860 struct pattern_list *patl;
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100861
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100862 /* allocate pattern */
863 patl = calloc(1, sizeof(*patl));
864 if (!patl) {
865 memprintf(err, "out of memory while indexing pattern");
866 return 0;
867 }
868
869 /* duplicate pattern */
870 memcpy(&patl->pat, pat, sizeof(*pat));
871 patl->pat.ptr.str = malloc(patl->pat.len + 1);
872 if (!patl->pat.ptr.str) {
873 free(patl);
874 memprintf(err, "out of memory while indexing pattern");
875 return 0;
876 }
877 memcpy(patl->pat.ptr.ptr, pat->ptr.ptr, pat->len);
878 patl->pat.ptr.str[patl->pat.len] = '\0';
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100879
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100880 /* chain pattern in the expression */
881 LIST_ADDQ(&expr->patterns, &patl->list);
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100882
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100883 /* that's ok */
884 return 1;
885}
886
887int pat_idx_list_reg(struct pattern_expr *expr, struct pattern *pat, char **err)
888{
889 struct pattern_list *patl;
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100890
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100891 /* allocate pattern */
892 patl = calloc(1, sizeof(*patl));
893 if (!patl) {
894 memprintf(err, "out of memory while indexing pattern");
895 return 0;
Thierry FOURNIER972028f2014-01-23 17:53:31 +0100896 }
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100897
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100898 /* duplicate pattern */
899 memcpy(&patl->pat, pat, sizeof(*pat));
900
901 /* allocate regex */
902 patl->pat.ptr.reg = calloc(1, sizeof(*patl->pat.ptr.reg));
903 if (!patl->pat.ptr.reg) {
904 free(patl);
905 memprintf(err, "out of memory while indexing pattern");
906 return 0;
907 }
908
909 /* compile regex */
910 if (!regex_comp(pat->ptr.reg->regstr, patl->pat.ptr.reg, !(patl->pat.flags & PAT_F_IGNORE_CASE), 0, err)) {
911 free(patl);
912 free(patl->pat.ptr.reg);
913 return 0;
914 }
915
916 /* free pattern method */
917 patl->pat.freeptrbuf = &pat_free_reg;
918
919 /* chain pattern in the expression */
920 LIST_ADDQ(&expr->patterns, &patl->list);
921
922 /* that's ok */
923 return 1;
924}
925
926int pat_idx_tree_ip(struct pattern_expr *expr, struct pattern *pat, char **err)
927{
928 unsigned int mask;
929 struct pat_idx_elt *node;
930
931 /* Only IPv4 can be indexed */
932 if (pat->type == SMP_T_IPV4) {
Thierry FOURNIER972028f2014-01-23 17:53:31 +0100933 /* in IPv4 case, check if the mask is contiguous so that we can
934 * insert the network into the tree. A continuous mask has only
935 * ones on the left. This means that this mask + its lower bit
936 * added once again is null.
937 */
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100938 mask = ntohl(pat->val.ipv4.mask.s_addr);
939 if (mask + (mask & -mask) == 0) {
940 mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100941
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100942 /* node memory allocation */
943 node = calloc(1, sizeof(*node) + 4);
944 if (!node) {
945 memprintf(err, "out of memory while loading pattern");
946 return 0;
947 }
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100948
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100949 /* copy the pointer to sample associated to this node */
950 node->smp = pat->smp;
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100951
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100952 /* FIXME: insert <addr>/<mask> into the tree here */
953 memcpy(node->node.key, &pat->val.ipv4.addr, 4); /* network byte order */
954 node->node.node.pfx = mask;
955 if (ebmb_insert_prefix(&expr->pattern_tree, &node->node, 4) != &node->node)
956 free(node); /* was a duplicate */
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100957
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100958 /* that's ok */
959 return 1;
960 }
961 }
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100962
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100963 /* If the value cannot be indexed, just add it to the list */
964 return pat_idx_list_val(expr, pat, err);
965}
966
967int pat_idx_tree_str(struct pattern_expr *expr, struct pattern *pat, char **err)
968{
969 int len;
970 struct pat_idx_elt *node;
971
972 /* Only string can be indexed */
973 if (pat->type != SMP_T_CSTR && pat->type != SMP_T_STR) {
974 memprintf(err, "internal error: string expected, but the type is '%s'",
975 smp_to_type[pat->type]);
976 return 0;
Thierry FOURNIER972028f2014-01-23 17:53:31 +0100977 }
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100978
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100979 /* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
980 if (pat->flags & PAT_F_IGNORE_CASE)
981 return pat_idx_list_str(expr, pat, err);
Thierry FOURNIER7148ce62013-12-06 19:06:43 +0100982
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100983 /* Process the key len */
984 len = strlen(pat->ptr.str) + 1;
985
986 /* node memory allocation */
987 node = calloc(1, sizeof(*node) + len);
988 if (!node) {
989 memprintf(err, "out of memory while loading pattern");
990 return 0;
Thierry FOURNIERed66c292013-11-28 11:05:19 +0100991 }
992
Thierry FOURNIERb9b08462013-12-13 15:12:32 +0100993 /* copy the pointer to sample associated to this node */
994 node->smp = pat->smp;
995
996 /* copy the string */
997 memcpy(node->node.key, pat->ptr.str, len);
998
999 /* index the new node */
1000 if (ebst_insert(&expr->pattern_tree, &node->node) != &node->node)
1001 free(node); /* was a duplicate */
1002
1003 /* that's ok */
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001004 return 1;
1005}
1006
Thierry FOURNIERb9b08462013-12-13 15:12:32 +01001007/* return 1 if the process is ok
1008 * return -1 if the parser fail. The err message is filled.
1009 * return -2 if out of memory
1010 */
1011int pattern_register(struct pattern_expr *expr, const char *arg,
1012 struct sample_storage *smp,
1013 int patflags, char **err)
1014{
1015 int ret;
1016 struct pattern pattern;
1017
1018 /* initialise pattern */
1019 memset(&pattern, 0, sizeof(pattern));
1020 pattern.flags = patflags;
1021 pattern.smp = smp;
1022
1023 /* parse pattern */
1024 ret = expr->parse(arg, &pattern, PAT_U_LOOKUP, err);
1025 if (!ret)
1026 return 0;
1027
1028 /* index pattern */
1029 if (!expr->index(expr, &pattern, err))
1030 return 0;
1031
1032 return 1;
1033}
1034
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001035/* Reads patterns from a file. If <err_msg> is non-NULL, an error message will
1036 * be returned there on errors and the caller will have to free it.
1037 */
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01001038int pattern_read_from_file(struct pattern_expr *expr,
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001039 const char *filename, int patflags,
1040 char **err)
1041{
1042 FILE *file;
1043 char *c;
1044 char *arg;
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001045 int ret = 0;
1046 int line = 0;
1047 int code;
1048
1049 file = fopen(filename, "r");
1050 if (!file) {
1051 memprintf(err, "failed to open pattern file <%s>", filename);
1052 return 0;
1053 }
1054
1055 /* now parse all patterns. The file may contain only one pattern per
1056 * line. If the line contains spaces, they will be part of the pattern.
1057 * The pattern stops at the first CR, LF or EOF encountered.
1058 */
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001059 while (fgets(trash.str, trash.size, file) != NULL) {
1060 line++;
1061 c = trash.str;
1062
1063 /* ignore lines beginning with a dash */
1064 if (*c == '#')
1065 continue;
1066
1067 /* strip leading spaces and tabs */
1068 while (*c == ' ' || *c == '\t')
1069 c++;
1070
1071
1072 arg = c;
1073 while (*c && *c != '\n' && *c != '\r')
1074 c++;
1075 *c = 0;
1076
1077 /* empty lines are ignored too */
1078 if (c == arg)
1079 continue;
1080
Thierry FOURNIERb9b08462013-12-13 15:12:32 +01001081 code = pattern_register(expr, arg, NULL, patflags, err);
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001082 if (code == -2) {
1083 memprintf(err, "out of memory when loading patterns from file <%s>", filename);
1084 goto out_close;
1085 }
1086 else if (code < 0) {
1087 memprintf(err, "%s when loading patterns from file <%s>", *err, filename);
Thierry FOURNIERb9b08462013-12-13 15:12:32 +01001088 goto out_close;
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001089 }
1090 }
1091
1092 ret = 1; /* success */
1093
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001094 out_close:
1095 fclose(file);
1096 return ret;
1097}
1098
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01001099/* This function matches a sample <smp> against a set of patterns presented in
1100 * pattern expression <expr>. Upon success, if <sample> is not NULL, it is fed
1101 * with the pointer associated with the matching pattern. This function returns
1102 * PAT_NOMATCH or PAT_MATCH.
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001103 */
Willy Tarreau0cba6072013-11-28 22:21:02 +01001104enum pat_match_res pattern_exec_match(struct pattern_expr *expr, struct sample *smp,
Thierry FOURNIER76090642013-12-10 15:03:38 +01001105 struct sample_storage **sample,
1106 struct pattern **pat, struct pat_idx_elt **idx_elt)
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001107{
Willy Tarreau0cba6072013-11-28 22:21:02 +01001108 enum pat_match_res pat_res = PAT_NOMATCH;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001109 struct pattern_list *pattern;
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001110 struct ebmb_node *node = NULL;
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01001111 struct pat_idx_elt *elt;
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001112
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01001113 if (expr->match == pat_match_nothing) {
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001114 if (smp->data.uint)
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01001115 pat_res |= PAT_MATCH;
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001116 else
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01001117 pat_res |= PAT_NOMATCH;
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001118 }
1119 else if (!expr->match) {
1120 /* just check for existence */
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01001121 pat_res |= PAT_MATCH;
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001122 }
1123 else {
1124 if (!eb_is_empty(&expr->pattern_tree)) {
1125 /* a tree is present, let's check what type it is */
Thierry FOURNIERe3ded592013-12-06 15:36:54 +01001126 if (expr->match == pat_match_str) {
1127 if (sample_convert(smp, SMP_T_STR))
1128 node = pat_lookup_str(smp, expr);
1129 }
1130 else if (expr->match == pat_match_ip) {
1131 if (sample_convert(smp, SMP_T_IPV4))
1132 node = pat_lookup_ip(smp, expr);
1133 }
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001134 if (node) {
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01001135 pat_res |= PAT_MATCH;
1136 elt = ebmb_entry(node, struct pat_idx_elt, node);
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001137 if (sample)
1138 *sample = elt->smp;
Thierry FOURNIER76090642013-12-10 15:03:38 +01001139 if (idx_elt)
1140 *idx_elt = elt;
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001141 }
1142 }
1143
1144 /* call the match() function for all tests on this value */
1145 list_for_each_entry(pattern, &expr->patterns, list) {
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01001146 if (pat_res == PAT_MATCH)
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001147 break;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001148 if (sample_convert(smp, pattern->pat.expect_type))
1149 pat_res |= expr->match(smp, &pattern->pat);
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001150 if (sample)
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001151 *sample = pattern->pat.smp;
Thierry FOURNIER76090642013-12-10 15:03:38 +01001152 if (pat)
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001153 *pat = &pattern->pat;
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001154 }
1155 }
1156
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01001157 return pat_res;
Thierry FOURNIERed66c292013-11-28 11:05:19 +01001158}
1159
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001160/* This function browse the pattern expr <expr> to lookup the key <key>. On
1161 * error it returns 0. On success, it returns 1 and fills either <pat_elt>
1162 * or <idx_elt> with the respectively matched pointers, and the other one with
1163 * NULL. Pointers are not set if they're passed as NULL.
1164 */
1165int pattern_lookup(const char *key, struct pattern_expr *expr,
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001166 struct pattern_list **pat_elt, struct pat_idx_elt **idx_elt, char **err)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001167{
1168 struct pattern pattern;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001169 struct pattern_list *pat;
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001170 struct ebmb_node *node;
1171 struct pat_idx_elt *elt;
Willy Tarreau668ae532013-12-15 16:42:26 +01001172 unsigned int mask = 0;
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001173
1174 /* no real pattern */
1175 if (!expr->match || expr->match == pat_match_nothing)
1176 return 0;
1177
1178 /* build lookup pattern */
Thierry FOURNIER580c32c2014-01-24 10:58:12 +01001179 if (!expr->parse(key, &pattern, PAT_U_LOOKUP, NULL))
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001180 return 0;
1181
1182 pat = NULL;
1183 elt = NULL;
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001184
Thierry FOURNIERc64de3f2013-12-10 15:08:39 +01001185 /* Try to look up the tree first. IPv6 is not indexed */
1186 if (!eb_is_empty(&expr->pattern_tree) && pattern.type != SMP_T_IPV6) {
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001187 /* Check the pattern type */
1188 if (pattern.type != SMP_T_STR &&
1189 pattern.type != SMP_T_CSTR &&
1190 pattern.type != SMP_T_IPV4) {
1191 memprintf(err, "Unexpected pattern type.");
1192 return 0;
1193 }
1194
1195 /* Convert mask. If the mask is not contiguous, ignore the lookup
1196 * in the tree, and browse the list.
1197 */
1198 if (expr->match == pat_match_ip) {
1199 mask = ntohl(pattern.val.ipv4.mask.s_addr);
1200 if (mask + (mask & -mask) != 0)
1201 goto browse_list;
1202 mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */
1203 }
1204
1205 /* browse each node of the tree, and check string */
1206 if (expr->match == pat_match_str) {
1207 for (node = ebmb_first(&expr->pattern_tree);
1208 node;
1209 node = ebmb_next(node)) {
1210 elt = container_of(node, struct pat_idx_elt, node);
1211 if (strcmp(pattern.ptr.str, (char *)elt->node.key) == 0)
1212 goto found;
1213 }
1214 }
1215 else if (expr->match == pat_match_ip) {
1216 for (node = ebmb_first(&expr->pattern_tree);
1217 node;
1218 node = ebmb_next(node)) {
1219 elt = container_of(node, struct pat_idx_elt, node);
1220 if (elt->node.node.pfx == mask &&
1221 memcmp(&pattern.val.ipv4.addr.s_addr, elt->node.key, 4) == 0)
1222 goto found;
1223 }
1224 }
1225 }
1226
1227browse_list:
Thierry FOURNIERc64de3f2013-12-10 15:08:39 +01001228 elt = NULL;
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001229 if (expr->parse == pat_parse_int ||
1230 expr->parse == pat_parse_len) {
1231 list_for_each_entry(pat, &expr->patterns, list) {
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001232 if (pat->pat.flags & PAT_F_TREE)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001233 continue;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001234 if (pattern.val.range.min_set != pat->pat.val.range.min_set)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001235 continue;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001236 if (pattern.val.range.max_set != pat->pat.val.range.max_set)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001237 continue;
1238 if (pattern.val.range.min_set &&
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001239 pattern.val.range.min != pat->pat.val.range.min)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001240 continue;
1241 if (pattern.val.range.max_set &&
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001242 pattern.val.range.max != pat->pat.val.range.max)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001243 continue;
1244 goto found;
1245 }
1246 }
1247 else if (expr->parse == pat_parse_ip) {
1248 list_for_each_entry(pat, &expr->patterns, list) {
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001249 if (pat->pat.flags & PAT_F_TREE)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001250 continue;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001251 if (pattern.type != pat->pat.type)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001252 continue;
1253 if (pattern.type == SMP_T_IPV4 &&
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001254 memcmp(&pattern.val.ipv4.addr, &pat->pat.val.ipv4.addr, sizeof(pat->pat.val.ipv4.addr)) != 0)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001255 continue;
1256 if (pattern.type == SMP_T_IPV4 &&
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001257 memcmp(&pattern.val.ipv4.mask, &pat->pat.val.ipv4.mask, sizeof(pat->pat.val.ipv4.addr)) != 0)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001258 continue;
1259 if (pattern.type == SMP_T_IPV6 &&
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001260 memcmp(&pattern.val.ipv6.addr, &pat->pat.val.ipv6.addr, sizeof(pat->pat.val.ipv6.addr)) != 0)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001261 continue;
1262 if (pattern.type == SMP_T_IPV6 &&
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001263 pattern.val.ipv6.mask != pat->pat.val.ipv6.mask)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001264 continue;
1265 goto found;
1266 }
1267 }
1268 else if (expr->parse == pat_parse_str) {
1269 list_for_each_entry(pat, &expr->patterns, list) {
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001270 if (pat->pat.flags & PAT_F_TREE)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001271 continue;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001272 if (pattern.len != pat->pat.len)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001273 continue;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001274 if (pat->pat.flags & PAT_F_IGNORE_CASE) {
1275 if (strncasecmp(pattern.ptr.str, pat->pat.ptr.str, pat->pat.len) != 0)
Thierry FOURNIER35249cb2014-01-14 13:38:40 +01001276 continue;
1277 }
1278 else {
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001279 if (strncmp(pattern.ptr.str, pat->pat.ptr.str, pat->pat.len) != 0)
Thierry FOURNIER35249cb2014-01-14 13:38:40 +01001280 continue;
1281 }
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001282 goto found;
1283 }
1284 }
1285 else if (expr->parse == pat_parse_bin) {
1286 list_for_each_entry(pat, &expr->patterns, list) {
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001287 if (pat->pat.flags & PAT_F_TREE)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001288 continue;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001289 if (pattern.len != pat->pat.len)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001290 continue;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001291 if (memcmp(pattern.ptr.ptr, pat->pat.ptr.ptr, pat->pat.len) != 0)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001292 continue;
1293 goto found;
1294 }
1295 }
1296 else if (expr->parse == pat_parse_reg) {
1297 list_for_each_entry(pat, &expr->patterns, list) {
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001298 if (pat->pat.flags & PAT_F_TREE)
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001299 continue;
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001300 if (pat->pat.flags & PAT_F_IGNORE_CASE) {
1301 if (strcasecmp(pattern.ptr.reg->regstr, pat->pat.ptr.reg->regstr) != 0)
Thierry FOURNIER35249cb2014-01-14 13:38:40 +01001302 continue;
1303 }
1304 else {
Thierry FOURNIER3ead5b92013-12-13 12:12:18 +01001305 if (strcmp(pattern.ptr.reg->regstr, pat->pat.ptr.reg->regstr) != 0)
Thierry FOURNIER35249cb2014-01-14 13:38:40 +01001306 continue;
1307 }
Thierry FOURNIER01cdcd42013-12-10 15:08:01 +01001308 goto found;
1309 }
1310 }
1311
1312 /* if we get there, we didn't find the pattern */
1313 return 0;
1314found:
1315 if (idx_elt)
1316 *idx_elt = elt;
1317
1318 if (pat_elt)
1319 *pat_elt = pat;
1320
1321 return 1;
1322}