xref: /netbsd/usr.sbin/pf/pfs/parse.y (revision 321a73e4)
1*321a73e4Sandvar /* $NetBSD: parse.y,v 1.4 2023/03/17 17:12:54 andvar Exp $ */
2ca38e323Sdegroote 
3ca38e323Sdegroote /*-
4ca38e323Sdegroote  * Copyright (c) 2010 The NetBSD Foundation, Inc.
5ca38e323Sdegroote  * All rights reserved.
6ca38e323Sdegroote  *
7ca38e323Sdegroote  * Redistribution and use in source and binary forms, with or without
8ca38e323Sdegroote  * modification, are permitted provided that the following conditions
9ca38e323Sdegroote  * are met:
10ca38e323Sdegroote  * 1. Redistributions of source code must retain the above copyright
11ca38e323Sdegroote  *    notice, this list of conditions and the following disclaimer.
12ca38e323Sdegroote  * 2. Redistributions in binary form must reproduce the above copyright
13ca38e323Sdegroote  *    notice, this list of conditions and the following disclaimer in the
14ca38e323Sdegroote  *    documentation and/or other materials provided with the distribution.
15ca38e323Sdegroote  *
16ca38e323Sdegroote  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17ca38e323Sdegroote  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18ca38e323Sdegroote  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19ca38e323Sdegroote  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20ca38e323Sdegroote  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21ca38e323Sdegroote  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22ca38e323Sdegroote  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23ca38e323Sdegroote  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24ca38e323Sdegroote  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25ca38e323Sdegroote  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26ca38e323Sdegroote  * POSSIBILITY OF SUCH DAMAGE.
27ca38e323Sdegroote  */
28ca38e323Sdegroote 
29ca38e323Sdegroote %{
30ca38e323Sdegroote #include <sys/cdefs.h>
31ca38e323Sdegroote 
32ca38e323Sdegroote #ifndef lint
33*321a73e4Sandvar __RCSID("$NetBSD: parse.y,v 1.4 2023/03/17 17:12:54 andvar Exp $");
34ca38e323Sdegroote #endif
35ca38e323Sdegroote 
36ca38e323Sdegroote #include <stdio.h>
37ca38e323Sdegroote #include <stdlib.h>
38ca38e323Sdegroote #include <string.h>
39ca38e323Sdegroote #include <stdint.h>
40ca38e323Sdegroote #include <stdbool.h>
41ca38e323Sdegroote #include <inttypes.h>
42ca38e323Sdegroote #include <errno.h>
43ca38e323Sdegroote 
44ca38e323Sdegroote #include <net/if.h>
45ca38e323Sdegroote #include <netinet/in.h>
46ca38e323Sdegroote #include <net/pfvar.h>
47ca38e323Sdegroote #include <arpa/inet.h>
48ca38e323Sdegroote #include <netdb.h>
49ca38e323Sdegroote #include <netinet/tcp_fsm.h>
50ca38e323Sdegroote 
51ca38e323Sdegroote #include "parser.h"
52ca38e323Sdegroote 
53f46c47f1Sjoerg int lineno;
54f46c47f1Sjoerg 
55f46c47f1Sjoerg struct pfioc_states* states;
56f46c47f1Sjoerg size_t allocated;
57f46c47f1Sjoerg 
58ca38e323Sdegroote // XXX it is really correct ?
59ca38e323Sdegroote extern const char * const tcpstates[];
60ca38e323Sdegroote 
61ca38e323Sdegroote 
62ca38e323Sdegroote struct pfsync_state global_state;
63ca38e323Sdegroote struct pfsync_state_peer *src_peer, *dst_peer;
64ca38e323Sdegroote struct pfsync_state_peer current_peer;
65ca38e323Sdegroote 
66ca38e323Sdegroote static void parse_init(void);
67ca38e323Sdegroote static void add_state(void);
68ca38e323Sdegroote static bool get_pfsync_host(const char*, struct pfsync_state_host*, sa_family_t*);
69ca38e323Sdegroote static uint8_t retrieve_peer_state(const char*, int);
70ca38e323Sdegroote static bool retrieve_seq(const char*, struct pfsync_state_peer*);
71ca38e323Sdegroote static bool strtou32(const char*, uint32_t*);
72ca38e323Sdegroote 
73ca38e323Sdegroote %}
74ca38e323Sdegroote 
75ca38e323Sdegroote %union {
76ca38e323Sdegroote 	uintmax_t num;
77ca38e323Sdegroote 	char* str;
78ca38e323Sdegroote }
79ca38e323Sdegroote 
80ca38e323Sdegroote %token STATE
81ca38e323Sdegroote %token IN OUT
82ca38e323Sdegroote %token ON PROTO
83ca38e323Sdegroote %token FROM TO USING
84ca38e323Sdegroote %token ID CID EXPIRE TIMEOUT
85ca38e323Sdegroote %token SRC DST
86ca38e323Sdegroote %token SEQ  MAX_WIN WSCALE MSS
87ca38e323Sdegroote %token NOSCRUB SCRUB FLAGS TTL MODE
88ca38e323Sdegroote %token NUMBER STRING
89ca38e323Sdegroote 
90ca38e323Sdegroote %type <str> STRING
91ca38e323Sdegroote %type <num> NUMBER
92ca38e323Sdegroote %%
93ca38e323Sdegroote 
94ca38e323Sdegroote states
95ca38e323Sdegroote 	: /* NOTHING */
96ca38e323Sdegroote 	| state states  { parse_init(); }
97ca38e323Sdegroote 	;
98ca38e323Sdegroote 
99ca38e323Sdegroote state
100ca38e323Sdegroote 	: STATE direction iface proto addrs id cid expire timeout src_peer dst_peer {
101ca38e323Sdegroote 			add_state();
102ca38e323Sdegroote 		}
103ca38e323Sdegroote 	;
104ca38e323Sdegroote 
105ca38e323Sdegroote direction
106ca38e323Sdegroote 	: IN {
107ca38e323Sdegroote 		   global_state.direction = PF_IN;
108ca38e323Sdegroote 		   src_peer = &global_state.dst;
109ca38e323Sdegroote 		   dst_peer = &global_state.src;
110ca38e323Sdegroote 		}
111ca38e323Sdegroote 	| OUT {
112ca38e323Sdegroote 			 global_state.direction = PF_OUT;
113ca38e323Sdegroote 			 src_peer = &global_state.src;
114ca38e323Sdegroote 			 dst_peer = &global_state.dst;
115ca38e323Sdegroote 		}
116ca38e323Sdegroote 	;
117ca38e323Sdegroote 
118ca38e323Sdegroote iface
119ca38e323Sdegroote 	: ON STRING {
120ca38e323Sdegroote 			strlcpy(global_state.ifname, $2, sizeof(global_state.ifname));
121ca38e323Sdegroote 			free($2);
122ca38e323Sdegroote 		}
123ca38e323Sdegroote 	;
124ca38e323Sdegroote 
125ca38e323Sdegroote proto
126ca38e323Sdegroote 	: PROTO STRING {
127ca38e323Sdegroote 			struct protoent *p;
128ca38e323Sdegroote 			p = getprotobyname($2);
129ca38e323Sdegroote 			if (p == NULL)
130ca38e323Sdegroote 				yyfatal("Invalid protocol name");
131ca38e323Sdegroote 			global_state.proto = p->p_proto;
132ca38e323Sdegroote 			free($2);
133ca38e323Sdegroote 			}
134ca38e323Sdegroote 	| PROTO NUMBER {
135ca38e323Sdegroote 			// check that the number may be valid proto ?
136ca38e323Sdegroote 			global_state.proto = $2;
137ca38e323Sdegroote 			}
138ca38e323Sdegroote 	;
139ca38e323Sdegroote 
140ca38e323Sdegroote addrs
141ca38e323Sdegroote 	: FROM STRING TO STRING {
142ca38e323Sdegroote 		get_pfsync_host($2, &global_state.lan, &global_state.af);
143ca38e323Sdegroote 		get_pfsync_host($4, &global_state.ext, &global_state.af);
144ca38e323Sdegroote 		memcpy(&global_state.gwy, &global_state.lan, sizeof(struct pfsync_state_host));
145ca38e323Sdegroote 		free($2);
146ca38e323Sdegroote 		free($4);
147ca38e323Sdegroote 		}
148ca38e323Sdegroote 	| FROM STRING TO STRING USING STRING {
149ca38e323Sdegroote 		get_pfsync_host($2, &global_state.lan, &global_state.af);
150ca38e323Sdegroote 		get_pfsync_host($4, &global_state.ext, &global_state.af);
151ca38e323Sdegroote 		get_pfsync_host($6, &global_state.gwy, &global_state.af);
152ca38e323Sdegroote 		free($2);
153ca38e323Sdegroote 		free($4);
154ca38e323Sdegroote 		free($6);
155ca38e323Sdegroote 		}
156ca38e323Sdegroote 	;
157ca38e323Sdegroote 
158ca38e323Sdegroote id
159ca38e323Sdegroote 	: ID NUMBER {
160ca38e323Sdegroote 			if ( $2 > UINT64_MAX)
161ca38e323Sdegroote 				yyfatal("id is too big");
162ca38e323Sdegroote 			uint64_t value = (uint64_t)$2;
163ca38e323Sdegroote 			memcpy(global_state.id, &value, sizeof(global_state.id));
164ca38e323Sdegroote 		}
165ca38e323Sdegroote 	;
166ca38e323Sdegroote 
167ca38e323Sdegroote cid
168ca38e323Sdegroote 	: CID NUMBER {
169ca38e323Sdegroote 			if ( $2 > UINT32_MAX)
170ca38e323Sdegroote 				yyfatal("creator id is too big");
171ca38e323Sdegroote 			global_state.creatorid = (uint32_t)$2;
172ca38e323Sdegroote 		}
173ca38e323Sdegroote 	;
174ca38e323Sdegroote 
175ca38e323Sdegroote expire
176ca38e323Sdegroote 	: EXPIRE NUMBER {
177ca38e323Sdegroote 			if ( $2 > UINT32_MAX)
178ca38e323Sdegroote 				yyfatal("expire time is too big");
179ca38e323Sdegroote 			global_state.expire = (uint32_t) $2;
180ca38e323Sdegroote 		}
181ca38e323Sdegroote 	;
182ca38e323Sdegroote 
183ca38e323Sdegroote timeout
184ca38e323Sdegroote 	: TIMEOUT NUMBER {
185ca38e323Sdegroote 			if ($2 > UINT8_MAX)
186ca38e323Sdegroote 				yyfatal("timeout time is too big");
187ca38e323Sdegroote 			global_state.timeout = (uint8_t) $2;
188ca38e323Sdegroote 		}
189ca38e323Sdegroote 	;
190ca38e323Sdegroote 
191ca38e323Sdegroote src_peer
192ca38e323Sdegroote 	: SRC peer {
193ca38e323Sdegroote 			memcpy(src_peer, &current_peer, sizeof(current_peer));
194ca38e323Sdegroote 		}
195ca38e323Sdegroote 	;
196ca38e323Sdegroote 
197ca38e323Sdegroote dst_peer
198ca38e323Sdegroote 	: DST peer {
199ca38e323Sdegroote 			memcpy(dst_peer, &current_peer, sizeof(current_peer));
200ca38e323Sdegroote 		}
201ca38e323Sdegroote 	;
202ca38e323Sdegroote 
203ca38e323Sdegroote peer
204ca38e323Sdegroote 	: peer_state scrub
205ca38e323Sdegroote 	| peer_state tcp_options scrub
206ca38e323Sdegroote 	;
207ca38e323Sdegroote 
208ca38e323Sdegroote peer_state
209ca38e323Sdegroote 	: STATE STRING {
210ca38e323Sdegroote 			current_peer.state = retrieve_peer_state($2, global_state.proto);
211ca38e323Sdegroote 			free($2);
212ca38e323Sdegroote 		}
213ca38e323Sdegroote 	| STATE	NUMBER {
214ca38e323Sdegroote 		if ( $2 > UINT8_MAX)
215ca38e323Sdegroote 			yyfatal("peer state is too big");
216ca38e323Sdegroote 		current_peer.state = $2;
217ca38e323Sdegroote 		}
218ca38e323Sdegroote 	;
219ca38e323Sdegroote 
220ca38e323Sdegroote tcp_options
221ca38e323Sdegroote 	: SEQ seqs MAX_WIN NUMBER WSCALE NUMBER {
222ca38e323Sdegroote 			if ($4 > UINT16_MAX)
223ca38e323Sdegroote 				yyfatal("max_win is too big");
224ca38e323Sdegroote 			current_peer.max_win = $4;
225ca38e323Sdegroote 
226ca38e323Sdegroote 			if ($6 > UINT8_MAX)
227ca38e323Sdegroote 				yyfatal("wscale is too big");
228ca38e323Sdegroote 			current_peer.wscale = $6;
229ca38e323Sdegroote 		}
230ca38e323Sdegroote 	| SEQ seqs MAX_WIN NUMBER WSCALE NUMBER MSS NUMBER {
231ca38e323Sdegroote 			if ($4 > UINT16_MAX)
232ca38e323Sdegroote 				yyfatal("max_win is too big");
233ca38e323Sdegroote 			current_peer.max_win = $4;
234ca38e323Sdegroote 
235ca38e323Sdegroote 			if ($6 > UINT8_MAX)
236ca38e323Sdegroote 				yyfatal("wscale is too big");
237ca38e323Sdegroote 			current_peer.wscale = $6;
238ca38e323Sdegroote 
239ca38e323Sdegroote 			if ($8 > UINT16_MAX)
240ca38e323Sdegroote 				yyfatal("mss is too big");
241ca38e323Sdegroote 			current_peer.mss = $8;
242ca38e323Sdegroote 		}
243ca38e323Sdegroote 	;
244ca38e323Sdegroote 
245ca38e323Sdegroote seqs
246ca38e323Sdegroote 	: STRING {
247ca38e323Sdegroote 		if (!retrieve_seq($1, &current_peer))
248ca38e323Sdegroote 			yyfatal("invalid seq number");
249ca38e323Sdegroote 
250ca38e323Sdegroote 		free($1);
251ca38e323Sdegroote 		}
252ca38e323Sdegroote 	;
253ca38e323Sdegroote 
254ca38e323Sdegroote scrub
255ca38e323Sdegroote 	: NOSCRUB { current_peer.scrub.scrub_flag= 0;}
256ca38e323Sdegroote 	| SCRUB FLAGS NUMBER MODE NUMBER TTL NUMBER {
257ca38e323Sdegroote 			current_peer.scrub.scrub_flag= PFSYNC_SCRUB_FLAG_VALID;
258ca38e323Sdegroote 			if ($3 > UINT16_MAX)
259ca38e323Sdegroote 				yyfatal("scrub flags is too big");
260ca38e323Sdegroote 			current_peer.scrub.pfss_flags = $3;
261ca38e323Sdegroote 
262ca38e323Sdegroote 			if ($5 > UINT32_MAX)
263ca38e323Sdegroote 				yyfatal("scrub mode is too big");
264ca38e323Sdegroote 			current_peer.scrub.pfss_ts_mod = $5;
265ca38e323Sdegroote 
266ca38e323Sdegroote 			if ($7 > UINT8_MAX)
267ca38e323Sdegroote 				yyfatal("scrub ttl is too big");
268ca38e323Sdegroote 			current_peer.scrub.pfss_ttl = $7;
269ca38e323Sdegroote 		}
270ca38e323Sdegroote 	;
271ca38e323Sdegroote 
272ca38e323Sdegroote 
273ca38e323Sdegroote %%
274ca38e323Sdegroote 
275ca38e323Sdegroote static void
276ca38e323Sdegroote parse_init(void)
277ca38e323Sdegroote {
278ca38e323Sdegroote 	memset(&global_state, 0, sizeof(global_state));
279ca38e323Sdegroote 	memset(&current_peer, 0, sizeof(current_peer));
280ca38e323Sdegroote 	src_peer = NULL;
281ca38e323Sdegroote 	dst_peer = NULL;
282ca38e323Sdegroote }
283ca38e323Sdegroote 
284ca38e323Sdegroote static bool
get_pfsync_host(const char * str,struct pfsync_state_host * host,sa_family_t * af)285ca38e323Sdegroote get_pfsync_host(const char* str, struct pfsync_state_host* host, sa_family_t* af)
286ca38e323Sdegroote {
287ca38e323Sdegroote 	size_t count_colon, addr_len, port_len;
288ca38e323Sdegroote 	const char* p, *last_colon, *first_bracket, *last_bracket;
289ca38e323Sdegroote 	char buf[48];
290ca38e323Sdegroote 	char buf_port[6];
291ca38e323Sdegroote 
292ca38e323Sdegroote 	if (str == NULL || *str == '\0')
293ca38e323Sdegroote 		return false;
294ca38e323Sdegroote 
295ca38e323Sdegroote 	p = str;
296ca38e323Sdegroote 	last_colon = NULL;
297ca38e323Sdegroote 	count_colon = 0;
298ca38e323Sdegroote 
299ca38e323Sdegroote 	while (*p != '\0') {
300ca38e323Sdegroote 		if (*p == ':') {
301ca38e323Sdegroote 			count_colon++;
302ca38e323Sdegroote 			last_colon = p;
303ca38e323Sdegroote 		}
304ca38e323Sdegroote 		p++;
305ca38e323Sdegroote 	}
306ca38e323Sdegroote 
307ca38e323Sdegroote 	/*
308ca38e323Sdegroote 	 * If no colon, it is not an expected addr
309ca38e323Sdegroote 	 * If there are more than one colon, we guess that af = AF_INET6
310ca38e323Sdegroote 	 */
311ca38e323Sdegroote 
312ca38e323Sdegroote 	if (count_colon == 0)
313ca38e323Sdegroote 		return false;
314ca38e323Sdegroote 
315ca38e323Sdegroote 	if (count_colon == 1)
316ca38e323Sdegroote 		*af = AF_INET;
317ca38e323Sdegroote 	else
318ca38e323Sdegroote 		*af = AF_INET6;
319ca38e323Sdegroote 
320ca38e323Sdegroote 	/*
321ca38e323Sdegroote 	 * First bracket must be next character after last colon
322ca38e323Sdegroote 	 * Last bracket must be the last character
323ca38e323Sdegroote 	 * distance between both must be <= 7
324ca38e323Sdegroote 	 */
325ca38e323Sdegroote 
326ca38e323Sdegroote 	if (*(last_colon+1) == '[')
327ca38e323Sdegroote 		first_bracket = last_colon + 1;
328ca38e323Sdegroote 	else
329ca38e323Sdegroote 		return false;
330ca38e323Sdegroote 
331ca38e323Sdegroote 	last_bracket = str + (strlen(str) - 1);
332ca38e323Sdegroote 	if (*last_bracket != ']')
333ca38e323Sdegroote 		return false;
334ca38e323Sdegroote 
335ca38e323Sdegroote 	port_len = last_bracket - first_bracket;
336ca38e323Sdegroote 	if (last_bracket - first_bracket > 7)
337ca38e323Sdegroote 		return false;
338ca38e323Sdegroote 
339ca38e323Sdegroote 	memcpy(buf_port, first_bracket +1, port_len - 1);
340ca38e323Sdegroote 	buf_port[port_len-1]= '\0';
341ca38e323Sdegroote 
342ca38e323Sdegroote 	addr_len = last_colon - str;
343ca38e323Sdegroote 	if (addr_len >= sizeof(buf))
344ca38e323Sdegroote 		return false;
345ca38e323Sdegroote 	memcpy(buf, str, addr_len);
346ca38e323Sdegroote 	buf[addr_len] = '\0';
347ca38e323Sdegroote 
348ca38e323Sdegroote 	if (inet_pton(*af, buf, &host->addr) != 1)
349ca38e323Sdegroote 		return false;
350ca38e323Sdegroote 
351ca38e323Sdegroote 	host->port = htons(atoi(buf_port));
352ca38e323Sdegroote 
353ca38e323Sdegroote 	return true;
354ca38e323Sdegroote }
355ca38e323Sdegroote 
356ca38e323Sdegroote static uint8_t
retrieve_peer_state(const char * str,int proto)357ca38e323Sdegroote retrieve_peer_state(const char* str, int proto)
358ca38e323Sdegroote {
359ca38e323Sdegroote 	uint8_t i;
360ca38e323Sdegroote 
361ca38e323Sdegroote 	if (proto == IPPROTO_TCP) {
362ca38e323Sdegroote 		i = 0;
363ca38e323Sdegroote 		while (i < TCP_NSTATES) {
364ca38e323Sdegroote 			if (strcmp(str, tcpstates[i]) == 0)
365ca38e323Sdegroote 				return i;
366ca38e323Sdegroote 			i++;
367ca38e323Sdegroote 		}
368ca38e323Sdegroote 		yyfatal("Invalid peer state");
369ca38e323Sdegroote 
370ca38e323Sdegroote 	} else {
371ca38e323Sdegroote 		if (proto == IPPROTO_UDP) {
372ca38e323Sdegroote 			const char* mystates[] = PFUDPS_NAMES;
373ca38e323Sdegroote 			i = 0;
374ca38e323Sdegroote 
375ca38e323Sdegroote 			while (i < PFUDPS_NSTATES) {
376ca38e323Sdegroote 				if (strcmp(str, mystates[i]) == 0)
377ca38e323Sdegroote 					return i;
378ca38e323Sdegroote 				i++;
379ca38e323Sdegroote 			}
380ca38e323Sdegroote 
381ca38e323Sdegroote 			yyfatal("Invalid peer state");
382ca38e323Sdegroote 		} else {
383ca38e323Sdegroote 			const char *mystates[] = PFOTHERS_NAMES;
384ca38e323Sdegroote 			i = 0;
385ca38e323Sdegroote 
386ca38e323Sdegroote 			while (i < PFOTHERS_NSTATES) {
387ca38e323Sdegroote 				if (strcmp(str, mystates[i]) == 0)
388ca38e323Sdegroote 					return i;
389ca38e323Sdegroote 				i++;
390ca38e323Sdegroote 			}
391ca38e323Sdegroote 
392ca38e323Sdegroote 			yyfatal("Invalid peer state");
393ca38e323Sdegroote 		}
394ca38e323Sdegroote 	}
395ca38e323Sdegroote      /*NOTREACHED*/
396ca38e323Sdegroote 	return 0;
397ca38e323Sdegroote }
398ca38e323Sdegroote 
399ca38e323Sdegroote static bool
strtou32(const char * str,uint32_t * res)400ca38e323Sdegroote strtou32(const char* str, uint32_t* res)
401ca38e323Sdegroote {
402ca38e323Sdegroote 	uintmax_t u;
403ca38e323Sdegroote 	errno = 0;
404ca38e323Sdegroote 	u = strtoumax(str, NULL, 10);
405ca38e323Sdegroote 	if (errno == ERANGE && u == UINTMAX_MAX)
406ca38e323Sdegroote 		return false;
407ca38e323Sdegroote 	if (u > UINT32_MAX)
408ca38e323Sdegroote 		return false;
409ca38e323Sdegroote 	*res = (uint32_t) u;
410ca38e323Sdegroote 	return true;
411ca38e323Sdegroote }
412ca38e323Sdegroote 
413ca38e323Sdegroote static bool
retrieve_seq(const char * str,struct pfsync_state_peer * peer)414ca38e323Sdegroote retrieve_seq(const char* str, struct pfsync_state_peer* peer)
415ca38e323Sdegroote {
416ca38e323Sdegroote 	const char* p, *p_colon, *p_comma;
417ca38e323Sdegroote 	char buf[100];
418ca38e323Sdegroote 	size_t size;
419ca38e323Sdegroote 
420ca38e323Sdegroote 	if (str == NULL || *str == '\0')
421ca38e323Sdegroote 		return false;
422ca38e323Sdegroote 
423ca38e323Sdegroote 	if (*str != '[' || *(str+(strlen(str) -1)) != ']')
424ca38e323Sdegroote 		return false;
425ca38e323Sdegroote 
426ca38e323Sdegroote 	p = str;
427ca38e323Sdegroote 	p_colon = NULL;
428ca38e323Sdegroote 	p_comma = NULL;
429ca38e323Sdegroote 	while (*p != '\0') {
430ca38e323Sdegroote 		if (*p == ':') {
431ca38e323Sdegroote 			if (p_colon !=NULL)
432ca38e323Sdegroote 				return false;
433ca38e323Sdegroote 			else
434ca38e323Sdegroote 				p_colon = p;
435ca38e323Sdegroote 		}
436ca38e323Sdegroote 
437ca38e323Sdegroote 		if (*p == ',') {
438ca38e323Sdegroote 			if (p_comma != NULL)
439ca38e323Sdegroote 				return false;
440ca38e323Sdegroote 			else
441ca38e323Sdegroote 				p_comma = p;
442ca38e323Sdegroote 		}
443ca38e323Sdegroote 		p++;
444ca38e323Sdegroote 	}
445ca38e323Sdegroote 
446ca38e323Sdegroote 	size = p_colon - str;
447ca38e323Sdegroote 	if (size > sizeof(buf))
448ca38e323Sdegroote 		return false;
449ca38e323Sdegroote 	memcpy(buf, str+1, size-1);
450ca38e323Sdegroote 	buf[size-1] = '\0';
451ca38e323Sdegroote 
452ca38e323Sdegroote 	if (!strtou32(buf, &peer->seqlo))
453ca38e323Sdegroote 		return false;
454ca38e323Sdegroote 
455ca38e323Sdegroote 
456ca38e323Sdegroote 	if (p_comma == NULL)
457ca38e323Sdegroote 		size = str + strlen(str) - 1 - p_colon;
458ca38e323Sdegroote 	else
459ca38e323Sdegroote 		size = p_comma - p_colon;
460ca38e323Sdegroote 
461ca38e323Sdegroote 	if (size > sizeof(buf))
462ca38e323Sdegroote 		return false;
463ca38e323Sdegroote 	memcpy(buf, p_colon+1, size -1);
464ca38e323Sdegroote 	buf[size-1] = '\0';
465ca38e323Sdegroote 
466ca38e323Sdegroote 	if (!strtou32(buf, &peer->seqhi))
467ca38e323Sdegroote 		return false;
468ca38e323Sdegroote 
469ca38e323Sdegroote 	if (p_comma == NULL) {
470ca38e323Sdegroote 		peer->seqdiff = 0;
471ca38e323Sdegroote 	} else {
472ca38e323Sdegroote 		size = str + strlen(str) - 1 - p_comma;
473ca38e323Sdegroote 		if (size > sizeof(buf))
474ca38e323Sdegroote 			return false;
475ca38e323Sdegroote 		memcpy(buf, p_comma +1, size -1);
476ca38e323Sdegroote 		buf[size-1] = '\0';
477ca38e323Sdegroote 
478ca38e323Sdegroote 		if (!strtou32(buf, &peer->seqdiff))
479ca38e323Sdegroote 			return false;
480ca38e323Sdegroote 	}
481ca38e323Sdegroote 
482ca38e323Sdegroote 	return true;
483ca38e323Sdegroote }
484ca38e323Sdegroote 
485ca38e323Sdegroote static void
add_state(void)486ca38e323Sdegroote add_state(void)
487ca38e323Sdegroote {
488ca38e323Sdegroote 
489ca38e323Sdegroote 	if (allocated == 0) {
490ca38e323Sdegroote 		allocated = 5;
491ca38e323Sdegroote 		states->ps_buf = malloc(allocated * sizeof(struct pfsync_state));
492ca38e323Sdegroote 		if (states->ps_buf == NULL)
493*321a73e4Sandvar 			yyfatal("Not enough memory");
494ca38e323Sdegroote 	}
495ca38e323Sdegroote 
496ca38e323Sdegroote 	if (allocated == (states->ps_len / sizeof(struct pfsync_state))) {
497ca38e323Sdegroote 		void *buf;
498ca38e323Sdegroote 		allocated = allocated * 2 + 1;
499ca38e323Sdegroote 		buf = realloc(states->ps_buf, allocated * sizeof(struct pfsync_state));
500ca38e323Sdegroote 		if (buf == NULL) {
501ca38e323Sdegroote 			free(states->ps_buf);
502*321a73e4Sandvar 			yyfatal("Not enough memory");
503ca38e323Sdegroote 		}
504ca38e323Sdegroote 		states->ps_buf = buf;
505ca38e323Sdegroote 	}
506ca38e323Sdegroote 
507ca38e323Sdegroote }
508