1 /*
2  * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2008,
3  *               2009, 2010, 2011, 2012, 2013, 2014, 2019, 2020, 2021
4  *      Inferno Nettverk A/S, Norway.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. The above copyright notice, this list of conditions and the following
10  *    disclaimer must appear in all copies of the software, derivative works
11  *    or modified versions, and any portions thereof, aswell as in all
12  *    supporting documentation.
13  * 2. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by
16  *      Inferno Nettverk A/S, Norway.
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * Inferno Nettverk A/S requests users of this software to return to
32  *
33  *  Software Distribution Coordinator  or  sdc@inet.no
34  *  Inferno Nettverk A/S
35  *  Oslo Research Park
36  *  Gaustadall�en 21
37  *  NO-0349 Oslo
38  *  Norway
39  *
40  * any improvements or extensions that they make and grant Inferno Nettverk A/S
41  * the rights to redistribute these changes.
42  *
43  */
44 
45 %{
46 
47 #if 0 /* XXX automatically added at head of generated .c file */
48 #include "common.h"
49 #endif
50 
51 static const char rcsid[] =
52 "$Id: config_scan.l,v 1.238.4.3.6.9 2021/02/02 19:34:12 karls Exp $";
53 
54 #include "yacconfig.h"
55 #include "config_parse.h"
56 
57 #define YY_STACK_USED 0
58 #define YY_ALWAYS_INTERACTIVE 0
59 #define YY_NEVER_INTERACTIVE 1
60 #define YY_MAIN 0
61 
62 #if SOCKS_CLIENT
63 /*
64  * stuff that is only defined in the server case, but which I don't know
65  * how #ifdef out in the lex pattern matching code instead.  Is it possible?
66  */
67 #define PROC_MOTHER    0
68 #define PROC_NEGOTIATE 0
69 #define PROC_REQUEST   0
70 #define PROC_IO        0
71 #define PROC_MONITOR   0
72 
73 #endif /* SOCKS_CLIENT */
74 
75 static int shouldresetstate(const int current_state, const int next_token);
76 /*
77  * If in state "current_state", and the next token is "next_token",
78  * should we reset the current state?
79  * Returns true if yes, false if not.
80  */
81 
82 
83 extern const int      socks_configtype;
84 extern int            lex_dorestart;
85 
86 char   currentlexline[100];   /* just to have some context. */
87 char   previouslexline[100];  /* just to have some context. */
88 static unsigned char ismask;
89 static int inroute, inclientrule;
90 
91 %}
92 
93 /*
94  * yylineno nonoptimal under flex, reason for 'find_rule' 'yy_flex_realloc'
95  * warnings.
96  */
97 %option yylineno
98 %option noyywrap
99 %option nounput
100 
101 /*%option debug                                             */
102 
103 WORDCHAR       [[:alpha:]]
104 NOT_WORDCHAR   [[^:alpha:]]
105 LS               ^[[:blank:]]*
106 
107 SOCKETLEVEL    (ip|socket|tcp|udp)
108 
109 
110    /* non-exclusive start conditions. */
111 %s start_address
112 %s start_port
113 
114    /* exclusive start conditions */
115 %x lineprefix
116 %x start_command
117 %x start_compatibility
118 %x start_line
119 %x start_log
120 %x start_loglevel
121 %x start_logoutput
122 %x start_logtype
123 %x start_errorsymbol
124 %x start_method
125 %x start_option
126 %x start_proxyprotocol
127 %x start_username
128 %x start_groupname
129 %x start_libwrapfile
130 %x start_cpuoption
131 %x start_hostindex
132 %x start_statekey
133 %x start_tcpoption
134 
135    /* ldap-stuff. */
136 %x start_ldapdomain
137 %x start_ldapbasedn
138 %x start_ldapurl
139 %x start_ldapfilter
140 %x start_ldapattribute
141 %x start_ldapservername
142 %x start_ldapgroupname
143 %x start_ldapkeytabname
144 %x start_ldapcertfile
145 %x start_ldapcertpath
146 
147 %x start_pacsidname
148 
149 %x start_alarmtest
150 %x start_srchost
151 %x start_protocol
152 %x start_servicename
153 %x start_portnumber
154 %x start_bsdauthstylename
155 %x start_gssapiservicename
156 %x start_gssapikeytabname
157 %x start_encryption
158 %x start_realmname
159 
160 %x start_socketprotocol
161 %x start_socketoption
162 %x start_socketoptionvalue
163 
164 %x start_processtype
165 %x start_schedulepolicy
166 %x start_schedulemask
167 %%
168 
169 %{
170 
171    if (lex_dorestart) {
172       lex_dorestart = 0;
173       inclientrule = inroute = 0;
174 
175       switch (socks_configtype) {
176          case CONFIGTYPE_SERVER:
177             return SERVERCONFIG;
178 
179          case CONFIGTYPE_CLIENT:
180             return CLIENTCONFIG;
181 
182          default:
183             SERRX(socks_configtype);
184       }
185    }
186 
187 
188 #if 0 /* does not work for some reason. */
189 \n.* {
190    const char *strip = " \n\t";
191    const char *p = currentlexline;
192 
193    SKIPLEADING(p, strip);
194    if (strlen(p) > 0)
195       strcpy(previouslexline, currentlexline);
196    /* else; blank line. */
197 
198    strncpy(currentlexline, yytext, sizeof(currentlexline) - 1);
199    currentlexline[sizeof(currentlexline) - 1] = NUL;
200 
201    ++yylineno;
202    yyless(1);
203 }
204 #endif
205 
206 %}
207 
208    /*
209     * start-condition dependent stuff.
210     */
211 
212 <start_protocol>ipv4 {
213    yylval.string = yytext;
214    return IPV4;
215 }
216 
217 <start_protocol>ipv6 {
218    yylval.string = yytext;
219    return IPV6;
220 }
221 
222 <start_tcpoption>ecn {
223    yylval.string = yytext;
224    return ECN;
225 }
226 
227 <start_tcpoption>sack {
228    yylval.string = yytext;
229    return SACK;
230 }
231 
232 <start_tcpoption>timestamps {
233    yylval.string = yytext;
234    return TIMESTAMPS;
235 }
236 
237 <start_tcpoption>wscale {
238    yylval.string = yytext;
239    return WSCALE;
240 }
241 
242 
243 <start_alarmtest>mtu-error {
244    yylval.string = yytext;
245    return MTU_ERROR;
246 }
247 
248 <start_statekey>from|hostid[^: /\t\n]* {
249    BEGIN(0);
250 
251    yylval.string = yytext;
252    return STATEKEY;
253 }
254 
255 <start_servicename>[a-zA-Z]+[^: /\t\n]* {
256    BEGIN(0);
257 
258    yylval.string = yytext;
259    return SERVICENAME;
260 }
261 
262 <start_proxyprotocol>socks_v4 {
263    yylval.string = yytext;
264    return PROXYPROTOCOL_SOCKS_V4;
265 }
266 
267 <start_proxyprotocol>socks_v5 {
268    yylval.string = yytext;
269    return PROXYPROTOCOL_SOCKS_V5;
270 }
271 
272 <start_proxyprotocol>http|http_v1.0 {
273    yylval.string = yytext;
274    return PROXYPROTOCOL_HTTP;
275 }
276 
277 <start_proxyprotocol>upnp {
278    yylval.string = yytext;
279    return PROXYPROTOCOL_UPNP;
280 }
281 
282 <start_command>bind {
283    yylval.string = yytext;
284    return COMMAND_BIND;
285 }
286 
287 <start_command>connect {
288    yylval.string = yytext;
289    return COMMAND_CONNECT;
290 }
291 
292 <start_command>udpassociate {
293    yylval.string = yytext;
294    return COMMAND_UDPASSOCIATE;
295 }
296 
297 <start_command>bindreply {
298    yylval.string = yytext;
299    return COMMAND_BINDREPLY;
300 }
301 
302 <start_command>udpreply {
303    yylval.string = yytext;
304    return COMMAND_UDPREPLY;
305 }
306 
307 
308 <start_address>(http|ftp)\:\/\/.* {
309    yylval.string = yytext;
310    return URL;
311 }
312 
313 <start_address>\. {
314    BEGIN(start_port);
315 
316    yylval.string = yytext;
317    return DOMAINNAME;
318 }
319 
320 <start_address>0/\/ {
321    /*
322     * For some reason can't get the above "0/\/" included in the
323     * address regexp below: "unrecognized rule" flex says.
324     */
325 
326    BEGIN(start_port);
327 
328    yylval.string = yytext;
329    return IPVANY;
330 }
331 
332 <start_address>([^ \t\n][^/ \t\n]+)|(::) {
333    struct sockaddr_storage addr, mask;
334    struct in6_addr ipv6;
335    struct in_addr ipv4;
336    char visbuf[256];
337 
338    BEGIN(start_port);
339 
340    yylval.string = yytext;
341 
342    /*
343     * we don't have a reliable regex to differentiate between a
344     * domainname and ifname on all systems.
345     * With a very general regex like the above, it is not so easy
346     * to exclude an ipaddress from matching it also.  So instead
347     * of continuing to try and create a perfect regex, do a brute force
348     * check to see what the text represents.
349     */
350 
351    if (socks_inet_pton(AF_INET, yytext, &ipv4, NULL) == 1)
352       return IPV4;
353 
354    if (socks_inet_pton(AF_INET6, yytext, &ipv6, NULL) == 1) {
355       if (IN6_IS_ADDR_V4MAPPED(&ipv6))
356          yyerrorx("we do not use IPv4-mapped IPv6 addresses.  Please specify "
357                   "a regular IPv4 address instead if you want use IPv4");
358       else
359          return IPV6;
360    }
361 
362    errno = 0;
363    if (ifname2sockaddr(yytext, 0, &addr, &mask) != NULL)
364       return IFNAME;
365    else {
366       if (ERRNOISNOFILE(errno))
367          yyerror("no free filedescriptors: can not access information on "
368                  "whether \"%s\" is a local NIC or not",
369                  str2vis(yytext, strlen(yytext), visbuf, sizeof(visbuf)));
370    }
371 
372    slog(LOG_DEBUG,
373         "\"%s\" appears to be neither ipaddress nor ifname; assuming hostname ",
374         yytext);
375 
376    return DOMAINNAME;
377 }
378 
379 <start_port>port {
380    yylval.string = yytext;
381    return PORT;
382 }
383 
384    /*
385     * cpu options.
386     */
387 
388 cpu {
389    BEGIN(start_cpuoption);
390 
391    yylval.string = yytext;
392    return CPU;
393 }
394 
395 <start_cpuoption>schedule {
396    BEGIN(start_processtype);
397 
398    ismask = 0;
399 
400    yylval.string = yytext;
401    return SCHEDULE;
402 }
403 
404 <start_cpuoption>mask {
405    BEGIN(start_processtype);
406 
407    ismask = 1;
408 
409    yylval.string = yytext;
410    return MASK;
411 }
412 
413 <start_processtype>mother {
414    BEGIN(ismask ? start_schedulemask : start_schedulepolicy);
415 
416    yylval.number = PROC_MOTHER;
417    return PROCESSTYPE;
418 }
419 
420 <start_processtype>monitor {
421    BEGIN(ismask ? start_schedulemask : start_schedulepolicy);
422 
423    yylval.number = PROC_MONITOR;
424    return PROCESSTYPE;
425 }
426 
427 <start_processtype>negotiate {
428    BEGIN(ismask ? start_schedulemask : start_schedulepolicy);
429 
430    yylval.number = PROC_NEGOTIATE;
431    return PROCESSTYPE;
432 }
433 
434 <start_processtype>request {
435    BEGIN(ismask ? start_schedulemask : start_schedulepolicy);
436 
437    yylval.number = PROC_REQUEST;
438    return PROCESSTYPE;
439 }
440 
441 <start_processtype>io {
442    BEGIN(ismask ? start_schedulemask : start_schedulepolicy);
443 
444    yylval.number = PROC_IO;
445    return PROCESSTYPE;
446 }
447 
448 <start_schedulemask>any {
449    BEGIN(0);
450 
451    yylval.number = CPUMASK_ANYCPU;
452    return NUMBER;
453 }
454 
455 <start_schedulepolicy>[^: 0-9\t/]+ {
456 #if SOCKS_CLIENT
457    SERRX(0);
458 
459 #else /* !SOCKS_CLIENT */
460 
461 #if HAVE_SCHED_SETSCHEDULER
462 
463    BEGIN(0);
464 
465    if ((yylval.number = cpupolicy2numeric(yytext)) == -1)
466       yyerrorx("unknown scheduling policy \"%s\"", yytext);
467 
468    return SCHEDULEPOLICY;
469 
470 #else /* !HAVE_SCHED_SETSCHEDULER */
471 
472    yyerrorx("setting cpu scheduling policy is not supported on this platform");
473 
474 #endif /* !HAVE_SCHED_SETSCHEDULER */
475 
476 #endif /* SOCKS_CLIENT */
477 }
478 
479 
480    /*
481      * socket option stuff.
482      */
483 
484 <start_socketprotocol>ip {
485    BEGIN(start_socketoption);
486 
487    yylval.number = IPPROTO_IP;
488    return SOCKETPROTOCOL;
489 }
490 
491 <start_socketprotocol>socket {
492    BEGIN(start_socketoption);
493 
494    yylval.number = SOL_SOCKET;
495    return SOCKETPROTOCOL;
496 }
497 
498 <start_socketprotocol>tcp {
499    BEGIN(start_socketoption);
500 
501    yylval.number = IPPROTO_TCP;
502    return SOCKETPROTOCOL;
503 }
504 
505 <start_socketprotocol>udp {
506    BEGIN(start_socketoption);
507 
508    yylval.number = IPPROTO_UDP;
509    return SOCKETPROTOCOL;
510 }
511 
512 
513 <start_socketoption>[-a-zA-Z_][-a-zA-Z_\.0-9]+ {
514    const sockopt_t *sockopt;
515 
516    BEGIN(start_socketoptionvalue);
517 
518    if ((sockopt = optname2sockopt(yytext)) == NULL)
519       yyerrorx("unknown socket option \"%s\"", yytext);
520 
521    yylval.number = (ssize_t)sockopt->optid;
522    return SOCKETOPTION_OPTID;
523 }
524 
525 <start_socketoptionvalue>[^: \t\n0-9][^ \t\n]+ {
526    BEGIN(0);
527 
528    yylval.string = yytext;
529    return SOCKETOPTION_SYMBOLICVALUE;
530 }
531 
532 <start_log>connect {
533    yylval.string = yytext;
534    return RULE_LOG_CONNECT;
535 }
536 
537 <start_log>data {
538    yylval.string = yytext;
539    return RULE_LOG_DATA;
540 }
541 
542 <start_log>disconnect {
543    yylval.string = yytext;
544    return RULE_LOG_DISCONNECT;
545 }
546 
547 <start_log>error {
548    yylval.string = yytext;
549    return RULE_LOG_ERROR;
550 }
551 
552 <start_log>iooperation|ioop {
553    yylval.string = yytext;
554    return RULE_LOG_IOOPERATION;
555 }
556 
557 <start_log>tcpinfo {
558    yylval.string = yytext;
559    return RULE_LOG_TCPINFO;
560 }
561 
562 <start_loglevel>[a-zA-Z]+/\. {
563    const loglevel_t *l;
564    char visbuf[256];
565 
566    BEGIN(start_logtype);
567 
568    if ((l = loglevel(yytext)) == NULL)
569       yyerror("unknown loglevel: \"%s\"",
570               str2vis(yytext, strlen(yytext), visbuf, sizeof(visbuf)));
571 
572    yylval.number = l->value;
573    return LOGLEVEL;
574 }
575 
576 <start_logtype>error {
577    BEGIN(start_errorsymbol);
578 
579    yylval.string = yytext;
580    return LOGTYPE_ERROR;
581 }
582 
583 <start_logtype>tcp\.disabled {
584    BEGIN(start_tcpoption);
585 
586    yylval.string = yytext;
587    return LOGTYPE_TCP_DISABLED;
588 }
589 
590 <start_logtype>tcp\.enabled {
591    BEGIN(start_tcpoption);
592 
593    yylval.string = yytext;
594    return LOGTYPE_TCP_ENABLED;
595 }
596 
597 
598 <start_errorsymbol>[a-zA-Z][^:[:space:]]+ {
599 #if !SOCKS_CLIENT
600 
601    /*
602     * Figure out what kind of error-symbol we are dealing with.
603     * Since we do not force the user to specify what kind of symbol
604     * he specifies, we have to try all variants.
605     */
606    if ((yylval.error.valuev = gaivalue(yytext)) != NULL)
607       yylval.error.valuetype = VALUETYPE_GAIERR;
608    else if ((yylval.error.valuev = errnovalue(yytext)) != NULL)
609       yylval.error.valuetype = VALUETYPE_ERRNO;
610 
611 #else /* SOCKS_CLIENT */
612 
613    yylval.error.valuev = NULL;
614 
615 #endif /* SOCKS_CLIENT */
616 
617    return ERRORVALUE;
618 }
619 
620 <start_bsdauthstylename>[a-zA-Z]+[^: /\t\n]* {
621    yylval.string = yytext;
622    return BSDAUTHSTYLENAME;
623 }
624 
625 <start_logoutput>[^: \t\n]+ {
626    yylval.string = yytext;
627    return LOGFILE;
628 }
629 
630 <start_username>[^: \t\n]+ {
631    yylval.string = yytext;
632    return USERNAME;
633 }
634 
635 <start_groupname>[^: \t\n]+ {
636    yylval.string = yytext;
637    return GROUPNAME;
638 }
639 
640 <start_libwrapfile>[^: \t\n]+ {
641    yylval.string = yytext;
642    return LIBWRAP_FILE;
643 }
644 
645 <start_ldapdomain>[^: \t\n]+[^\t\n]+ {
646    yylval.string = yytext;
647    return LDAP_DOMAIN;
648 }
649 
650 <start_ldapbasedn>[^: \t\n]+[^\t\n]+ {
651    yylval.string = yytext;
652    return LDAP_BASEDN;
653 }
654 
655 <start_ldapfilter>[^: \t\n]+[^\t\n]+ {
656    yylval.string = yytext;
657    return LDAP_FILTER;
658 }
659 
660 <start_ldapurl>(ldap|ldaps)\:\/\/.* {
661    yylval.string = yytext;
662    return LDAP_URL;
663 }
664 
665 <start_ldapattribute>[^: \t\n]+[^\t\n]+ {
666    yylval.string = yytext;
667    return LDAP_ATTRIBUTE;
668 }
669 
670 <start_ldapgroupname>[^: \t\n]+[^\t\n]+ {
671    yylval.string = yytext;
672    return LDAPGROUP_NAME;
673 }
674 
675 <start_ldapservername>[^: \t\n]+[^\t\n]+ {
676    yylval.string = yytext;
677    return LDAPSERVER_NAME;
678 }
679 
680 <start_ldapcertfile>[^: \t\n]+ {
681    yylval.string = yytext;
682    return LDAP_CERTFILE;
683 }
684 
685 <start_ldapcertpath>[^: \t\n]+ {
686    yylval.string = yytext;
687    return LDAP_CERTPATH;
688 }
689 
690 <start_ldapkeytabname>[^: \t\n]+ {
691    yylval.string = yytext;
692    return LDAPKEYTABNAME;
693 }
694 
695 <start_ldapkeytabname>FILE:[^ \t\n]+ {
696    yylval.string = yytext;
697    return LDAPKEYTABNAME;
698 }
699 
700 <start_pacsidname>[^: \t\n]+[^\t\n]+ {
701    yylval.string = yytext;
702    return PACSID_NAME;
703 }
704 
705 <start_gssapikeytabname>[^: \t\n]+ {
706    yylval.string = yytext;
707    return GSSAPIKEYTABNAME;
708 }
709 
710 <start_gssapikeytabname>FILE:[^ \t\n]+ {
711    yylval.string = yytext;
712    return GSSAPIKEYTABNAME;
713 }
714 
715 <start_gssapiservicename>[^: \t\n]+ {
716    yylval.string = yytext;
717    return GSSAPISERVICENAME;
718 }
719 
720 <lineprefix>: {
721    BEGIN(start_line);
722 
723    yylval.string = yytext;
724    return *yytext;
725 }
726 
727 <start_line>.* {
728    BEGIN(0);
729 
730    yylval.string = yytext;
731    return LINE;
732 }
733 
734 <start_srchost>nodnsmismatch {
735    yylval.string = yytext;
736    return NODNSMISMATCH;
737 }
738 
739 <start_srchost>nodnsunknown {
740    yylval.string = yytext;
741    return NODNSUNKNOWN;
742 }
743 
744 <start_srchost>checkreplyauth {
745    yylval.string = yytext;
746    return CHECKREPLYAUTH;
747 }
748 
749 <start_protocol>tcp {
750    yylval.string = yytext;
751    return PROTOCOL_TCP;
752 }
753 
754 <start_protocol>udp {
755    yylval.string = yytext;
756    return PROTOCOL_UDP;
757 }
758 
759 <start_protocol>fake {
760    yylval.string = yytext;
761    return PROTOCOL_FAKE;
762 }
763 
764 <start_encryption>any {
765    yylval.string = yytext;
766    return GSSAPIENC_ANY;
767 }
768 
769 <start_encryption>clear {
770    yylval.string = yytext;
771    return GSSAPIENC_CLEAR;
772 }
773 
774 <start_encryption>integrity {
775    yylval.string = yytext;
776    return GSSAPIENC_INTEGRITY;
777 }
778 
779 <start_encryption>confidentiality {
780    yylval.string = yytext;
781    return GSSAPIENC_CONFIDENTIALITY;
782 }
783 
784 <start_encryption>permessage {
785    yylval.string = yytext;
786    return GSSAPIENC_PERMESSAGE;
787 }
788 
789 <start_realmname>[^: \t\n]+ {
790    yylval.string = yytext;
791    return REALNAME;
792 }
793 
794 <start_method>none {
795    yylval.method = AUTHMETHOD_NONE;
796    return METHODNAME;
797 }
798 
799 <start_method>gssapi {
800    yylval.method = AUTHMETHOD_GSSAPI;
801    return METHODNAME;
802 }
803 
804 <start_method>username {
805    yylval.method = AUTHMETHOD_UNAME;
806    return METHODNAME;
807 }
808 
809 <start_method>rfc931 {
810    yylval.method = AUTHMETHOD_RFC931;
811    return METHODNAME;
812 }
813 
814 <start_method>pam.any {
815    yylval.number = AUTHMETHOD_PAM_ANY;
816    return METHODNAME;
817 }
818 
819 <start_method>pam.address {
820    yylval.method = AUTHMETHOD_PAM_ADDRESS;
821    return METHODNAME;
822 }
823 
824 <start_method>pam.username {
825    yylval.method = AUTHMETHOD_PAM_USERNAME;
826    return METHODNAME;
827 }
828 
829 <start_method>pam {
830    yywarnx_deprecated(yytext, "pam.*");
831 
832    yylval.method = AUTHMETHOD_PAM_USERNAME;
833    return METHODNAME;
834 }
835 
836 
837 <start_method>bsdauth {
838    yylval.method = AUTHMETHOD_BSDAUTH;
839    return METHODNAME;
840 }
841 
842 <start_method>ldapauth {
843    yylval.method = AUTHMETHOD_LDAPAUTH;
844    return METHODNAME;
845 }
846 
847    /* non-start condition dependents. */
848 
849 eq|=|ne|!=|ge|>=|le|<=|gt|>|lt|< {
850    BEGIN(start_servicename);
851 
852    yylval.string = yytext;
853    return OPERATOR;
854 }
855 
856 {LS}client/[ ]+(pass|block) {
857    inclientrule = 1;
858 
859    yylval.string = yytext;
860    return CLIENTRULE;
861 }
862 
863 {LS}hostid/[ ]+(pass|block) {
864    yylval.string = yytext;
865    return HOSTIDRULE;
866 }
867 
868 {LS}socks/[ ]+(pass|block) {
869    yylval.string = yytext;
870    return SOCKSRULE;
871 }
872 
873 {LS}(pass|block) { /* deprecated socks rule  syntax, without "socks "-prefix. */
874 #if SOCKS_CLIENT
875 
876    yyerrorx("pass/block rules are not used in the client");
877 
878 #else /* server */
879    char old[256], new[256];
880 
881    snprintf(old, sizeof(old), "%s", yytext);
882    STRIPTRAILING(old, strlen(old), " \t");
883 
884    snprintf(new, sizeof(new), "socks %s", old);
885 
886    yywarnx_deprecated(old, new);
887 
888    yyless(0);
889 
890    return SOCKSRULE;
891 
892 #endif /* server */
893 }
894 
895 
896 alarm.data {
897    yylval.string = yytext;
898    return ALARMTYPE_DATA;
899 }
900 
901 alarm.disconnect {
902    yylval.string = yytext;
903    return ALARMTYPE_DISCONNECT;
904 }
905 
906 alarm/\. {
907    BEGIN(start_alarmtest);
908 
909    yylval.string = yytext;
910    return ALARM;
911 }
912 
913 
914 \.recv/[[:space:]]*: {
915    yylval.string = yytext;
916    return RECVSIDE;
917 }
918 
919 \.send/[[:space:]]*: {
920    yylval.string = yytext;
921    return SENDSIDE;
922 }
923 
924 debug {
925    yylval.string = yytext;
926    return DEBUGGING;
927 }
928 
929 {LS}route {
930    inroute = 1;
931 
932    yylval.string = yytext;
933    return ROUTE;
934 }
935 
936 route {
937    yylval.string = yytext;
938    return ROUTE;
939 }
940 
941 
942 route\. {
943    yylval.string = yytext;
944    return GLOBALROUTEOPTION;
945 }
946 
947 
948 maxfail {
949    yylval.string = yytext;
950    return MAXFAIL;
951 }
952 
953 badexpire {
954    yylval.string = yytext;
955    return BADROUTE_EXPIRE;
956 }
957 
958 resolveprotocol {
959    BEGIN(start_protocol);
960 
961    yylval.string = yytext;
962    return RESOLVEPROTOCOL;
963 }
964 
965 srchost {
966    BEGIN(start_srchost);
967 
968    yylval.string = yytext;
969    return SRCHOST;
970 }
971 
972 proxyprotocol {
973    BEGIN(start_proxyprotocol);
974 
975    yylval.string = yytext;
976    return PROXYPROTOCOL;
977 }
978 
979 errorlog {
980    BEGIN(start_logoutput);
981 
982    yylval.string = yytext;
983    return ERRORLOG;
984 }
985 
986 logoutput {
987    BEGIN(start_logoutput);
988 
989    yylval.string = yytext;
990    return LOGOUTPUT;
991 }
992 
993 
994 protocol {
995    BEGIN(start_protocol);
996 
997    yylval.string = yytext;
998    return PROTOCOL;
999 }
1000 
1001 command {
1002    BEGIN(start_command);
1003 
1004    yylval.string = yytext;
1005    return COMMAND;
1006 }
1007 
1008 udp\.portrange {
1009    yylval.string = yytext;
1010    return UDPPORTRANGE;
1011 }
1012 
1013 udp\.connectdst {
1014    yylval.string = yytext;
1015    return UDPCONNECTDST;
1016 }
1017 
1018 redirect {
1019    yylval.string = yytext;
1020    return REDIRECT;
1021 }
1022 
1023 bandwidth {
1024    yylval.string = yytext;
1025    return BANDWIDTH;
1026 }
1027 
1028 session\.max {
1029    yylval.string = yytext;
1030    return SESSIONMAX;
1031 }
1032 
1033 session\.inheritable {
1034    yylval.string = yytext;
1035    return SESSION_INHERITABLE;
1036 }
1037 
1038 session\.throttle {
1039    yylval.string = yytext;
1040    return SESSIONTHROTTLE;
1041 }
1042 
1043 session\.state.key {
1044    BEGIN(start_statekey);
1045 
1046    yylval.string = yytext;
1047    return SESSIONSTATE_KEY;
1048 }
1049 
1050 session\.state.throttle {
1051    yylval.string = yytext;
1052    return SESSIONSTATE_THROTTLE;
1053 }
1054 
1055 session\.state.max {
1056    yylval.string = yytext;
1057    return SESSIONSTATE_MAX;
1058 }
1059 
1060 
1061 in {
1062    yylval.string = yytext;
1063    return WORD__IN;
1064 }
1065 
1066 from {
1067    BEGIN(start_address);
1068 
1069    yylval.string = yytext;
1070    return FROM;
1071 }
1072 
1073 to {
1074    BEGIN(start_address);
1075 
1076    yylval.string = yytext;
1077    return TO;
1078 }
1079 
1080 via {
1081    BEGIN(start_address);
1082 
1083    yylval.string = yytext;
1084    return VIA;
1085 }
1086 
1087 yes {
1088    yylval.string = yytext;
1089    return YES;
1090 }
1091 
1092 no {
1093    yylval.string = yytext;
1094    return NO;
1095 }
1096 
1097 internal\./{SOCKETLEVEL}\. {
1098    BEGIN(start_socketprotocol);
1099 
1100    yylval.string = yytext;
1101    return INTERNALSOCKET;
1102 }
1103 
1104 internal\./alarm\. {
1105    yylval.string = yytext;
1106    return ALARMIF_INTERNAL;
1107 }
1108 
1109 internal\.log/\. {
1110    BEGIN(start_loglevel);
1111 
1112    yylval.string = yytext;
1113    return LOGIF_INTERNAL;
1114 }
1115 
1116 internal\.protocol {
1117    BEGIN(start_protocol);
1118 
1119    yylval.string = yytext;
1120    return INTERNAL_PROTOCOL;
1121 }
1122 
1123 
1124 internal/[[:space:]]*: {
1125    BEGIN(start_address);
1126 
1127    yylval.string = yytext;
1128    return INTERNAL;
1129 }
1130 
1131 
1132 external\./{SOCKETLEVEL}\. {
1133    BEGIN(start_socketprotocol);
1134 
1135    yylval.string = yytext;
1136    return EXTERNALSOCKET;
1137 }
1138 
1139 external\./alarm\. {
1140    yylval.string = yytext;
1141    return ALARMIF_EXTERNAL;
1142 }
1143 
1144 external\.protocol {
1145    BEGIN(start_protocol);
1146 
1147    yylval.string = yytext;
1148    return EXTERNAL_PROTOCOL;
1149 }
1150 
1151 external\.rotation {
1152    yylval.string = yytext;
1153    return EXTERNAL_ROTATION;
1154 }
1155 
1156 external\.log/\. {
1157    BEGIN(start_loglevel);
1158 
1159    yylval.string = yytext;
1160    return LOGIF_EXTERNAL;
1161 }
1162 
1163 external/[[:space:]]*: {
1164    BEGIN(start_address);
1165 
1166    yylval.string = yytext;
1167    return EXTERNAL;
1168 }
1169 
1170 none {
1171    yylval.string = yytext;
1172    return NONE;
1173 }
1174 
1175 same-same {
1176    yylval.string = yytext;
1177    return SAMESAME;
1178 }
1179 
1180 
1181 child\.maxidle.*:.* {
1182    yywarnx_deprecated(yytext, NULL);
1183 }
1184 
1185 child\.maxrequests {
1186    yylval.string = yytext;
1187    return PROC_MAXREQUESTS;
1188 }
1189 
1190 child\.maxlifetime {
1191    yylval.string = yytext;
1192    return PROC_MAXLIFETIME;
1193 }
1194 
1195 user {
1196    BEGIN(start_username);
1197 
1198    yylval.string = yytext;
1199    return USER;
1200 }
1201 
1202 group {
1203    BEGIN(start_groupname);
1204 
1205    yylval.string = yytext;
1206    return GROUP;
1207 }
1208 
1209 user\.privileged {
1210    BEGIN(start_username);
1211 
1212    yylval.string = yytext;
1213    return USER_PRIVILEGED;
1214 }
1215 
1216 user\.unprivileged|user\.notprivileged {
1217    BEGIN(start_username);
1218 
1219    yylval.string = yytext;
1220    return USER_UNPRIVILEGED;
1221 }
1222 
1223 user\.libwrap {
1224    BEGIN(start_username);
1225 
1226    yylval.string = yytext;
1227    return USER_LIBWRAP;
1228 }
1229 
1230 timeout\.connect {
1231    yylval.string = yytext;
1232    return CONNECTTIMEOUT;
1233 }
1234 
1235 timeout\.tcp_fin_wait {
1236    yylval.string = yytext;
1237    return TCP_FIN_WAIT;
1238 }
1239 
1240 
1241 timeout\.io {
1242    yylval.string = yytext;
1243    return IOTIMEOUT;
1244 }
1245 
1246 timeout\.io\.tcp {
1247    yylval.string = yytext;
1248    return IOTIMEOUT_TCP;
1249 }
1250 
1251 timeout\.io\.udp {
1252    yylval.string = yytext;
1253    return IOTIMEOUT_UDP;
1254 }
1255 
1256 timeout\.negotiate {
1257    yylval.string = yytext;
1258    return NEGOTIATETIMEOUT;
1259 }
1260 
1261 
1262 compatibility {
1263    yylval.string = yytext;
1264    return COMPATIBILITY;
1265 }
1266 
1267 sameport {
1268    yylval.string = yytext;
1269    return SAMEPORT;
1270 }
1271 
1272 draft-5.05 {
1273    yylval.string = yytext;
1274    return DRAFT_5_05;
1275 }
1276 
1277 clientcompatibility {
1278    yylval.string = yytext;
1279    return CLIENTCOMPATIBILITY;
1280 }
1281 
1282 necgssapi {
1283    yylval.string = yytext;
1284    return NECGSSAPI;
1285 }
1286 
1287 extension {
1288    yylval.string = yytext;
1289    return EXTENSION;
1290 }
1291 
1292 bind {
1293    yylval.string = yytext;
1294    return BIND;
1295 }
1296 
1297 hostid {
1298    BEGIN(start_address);
1299 
1300    yylval.string = yytext;
1301    return HOSTID;
1302 }
1303 
1304 monitor {
1305    yylval.string = yytext;
1306    return MONITOR;
1307 }
1308 
1309 <start_statekey,INITIAL>hostindex {
1310    BEGIN(start_hostindex);
1311 
1312    yylval.string = yytext;
1313    return HOSTINDEX;
1314 }
1315 
1316 <start_hostindex>any {
1317    BEGIN(0);
1318 
1319    yylval.number = 0;
1320    return NUMBER;
1321 }
1322 
1323 
1324 socksmethod {
1325    BEGIN(start_method);
1326 
1327    yylval.string = yytext;
1328    return SOCKSMETHOD;
1329 }
1330 
1331 clientmethod {
1332    BEGIN(start_method);
1333 
1334    yylval.string = yytext;
1335    return CLIENTMETHOD;
1336 }
1337 
1338 method {
1339    BEGIN(start_method);
1340 
1341    yylval.string = yytext;
1342 
1343    if (inroute)
1344       return METHOD;
1345    else if (inclientrule) {
1346       yywarnx_deprecated(yytext, "clientmethod");
1347       return CLIENTMETHOD;
1348    }
1349    else /* anywhere else; must be socksmethod. */
1350       yywarnx_deprecated(yytext, "socksmethod");
1351 
1352    return SOCKSMETHOD;
1353 }
1354 
1355 
1356    /* filterrules */
1357 
1358    /*
1359     * verdicts
1360     */
1361 
1362 block {
1363    yylval.string = yytext;
1364    return VERDICT_BLOCK;
1365 }
1366 
1367 pass {
1368    yylval.string = yytext;
1369    return VERDICT_PASS;
1370 }
1371 
1372 log/: {
1373    BEGIN(start_log);
1374 
1375    yylval.string = yytext;
1376    return RULE_LOG;
1377 }
1378 
1379 
1380 libwrap {
1381    BEGIN(lineprefix);
1382 
1383    yylval.string = yytext;
1384    return LIBWRAPSTART;
1385 }
1386 
1387 libwrap\.allow {
1388    BEGIN(start_libwrapfile);
1389 
1390    yylval.string = yytext;
1391    return LIBWRAP_ALLOW;
1392 }
1393 
1394 libwrap\.deny {
1395    BEGIN(start_libwrapfile);
1396 
1397    yylval.string = yytext;
1398    return LIBWRAP_DENY;
1399 }
1400 
1401 libwrap\.hosts_access {
1402    yylval.string = yytext;
1403    return LIBWRAP_HOSTS_ACCESS;
1404 }
1405 
1406 pam\.servicename|pamservicename {
1407    BEGIN(start_servicename);
1408 
1409    yylval.string = yytext;
1410    return PAMSERVICENAME;
1411 }
1412 
1413 bsdauth\.stylename {
1414    BEGIN(start_bsdauthstylename);
1415 
1416    yylval.string = yytext;
1417    return BSDAUTHSTYLE;
1418 }
1419 
1420 gssapi\.servicename {
1421    BEGIN(start_gssapiservicename);
1422 
1423    yylval.string = yytext;
1424    return GSSAPISERVICE;
1425 }
1426 
1427 gssapi\.keytab {
1428        BEGIN(start_gssapikeytabname);
1429 
1430    yylval.string = yytext;
1431    return GSSAPIKEYTAB;
1432 }
1433 
1434 gssapi\.enctype {
1435        BEGIN(start_encryption);
1436 
1437    yylval.string = yytext;
1438    return GSSAPIENCTYPE;
1439 }
1440 
1441 ldap\.basedn {
1442        BEGIN(start_ldapbasedn);
1443 
1444    yylval.string = yytext;
1445    return LDAPBASEDN;
1446 }
1447 
1448 ldap\.basedn\.hex {
1449        BEGIN(start_ldapbasedn);
1450 
1451    yylval.string = yytext;
1452    return LDAPBASEDN_HEX;
1453 }
1454 
1455 ldap\.basedn\.hex\.all {
1456        BEGIN(start_ldapbasedn);
1457 
1458    yylval.string = yytext;
1459    return LDAPBASEDN_HEX_ALL;
1460 }
1461 
1462 ldap\.auth\.basedn {
1463        BEGIN(start_ldapbasedn);
1464 
1465    yylval.string = yytext;
1466    return LDAPAUTHBASEDN;
1467 }
1468 
1469 ldap\.auth\.basedn\.hex {
1470        BEGIN(start_ldapbasedn);
1471 
1472    yylval.string = yytext;
1473    return LDAPAUTHBASEDN_HEX;
1474 }
1475 
1476 ldap\.auth\.basedn\.hex\.all {
1477        BEGIN(start_ldapbasedn);
1478 
1479    yylval.string = yytext;
1480    return LDAPAUTHBASEDN_HEX_ALL;
1481 }
1482 
1483 ldap\.port {
1484    yylval.string = yytext;
1485    return LDAPPORT;
1486 }
1487 
1488 ldap\.auth\.port {
1489    yylval.string = yytext;
1490    return LDAPAUTHPORT;
1491 }
1492 
1493 ldap\.port\.ssl {
1494    yylval.string = yytext;
1495    return LDAPPORTSSL;
1496 }
1497 
1498 ldap\.auth\.port\.ssl {
1499    yylval.string = yytext;
1500    return LDAPAUTHPORTSSL;
1501 }
1502 
1503 ldap\.url {
1504        BEGIN(start_ldapurl);
1505 
1506    yylval.string = yytext;
1507    return LDAPURL;
1508 }
1509 
1510 ldap\.auth\.url {
1511        BEGIN(start_ldapurl);
1512 
1513    yylval.string = yytext;
1514    return LDAPAUTHURL;
1515 }
1516 
1517 ldap\.certfile {
1518    BEGIN(start_ldapcertfile);
1519 
1520    yylval.string = yytext;
1521    return LDAPCERTFILE;
1522 }
1523 
1524 ldap\.auth\.certfile {
1525    BEGIN(start_ldapcertfile);
1526 
1527    yylval.string = yytext;
1528    return LDAPAUTHCERTFILE;
1529 }
1530 
1531 ldap\.certpath {
1532    BEGIN(start_ldapcertpath);
1533 
1534    yylval.string = yytext;
1535    return LDAPCERTPATH;
1536 }
1537 
1538 ldap\.auth\.certpath {
1539    BEGIN(start_ldapcertpath);
1540 
1541    yylval.string = yytext;
1542    return LDAPAUTHCERTPATH;
1543 }
1544 
1545 ldap\.domain {
1546        BEGIN(start_ldapdomain);
1547 
1548    yylval.string = yytext;
1549    return LDAPDOMAIN;
1550 }
1551 
1552 ldap\.auth\.domain {
1553        BEGIN(start_ldapdomain);
1554 
1555    yylval.string = yytext;
1556    return LDAPAUTHDOMAIN;
1557 }
1558 
1559 ldap\.debug {
1560    yylval.string = yytext;
1561    return LDAPDEBUG;
1562 }
1563 
1564 ldap\.auth\.debug {
1565    yylval.string = yytext;
1566    return LDAPAUTHDEBUG;
1567 }
1568 
1569 ldap\.mdepth {
1570    yylval.string = yytext;
1571    return LDAPDEPTH;
1572 }
1573 
1574 ldap\.ssl {
1575    yylval.string = yytext;
1576    return LDAPSSL;
1577 }
1578 
1579 ldap\.auth\.ssl {
1580    yylval.string = yytext;
1581    return LDAPAUTHSSL;
1582 }
1583 
1584 ldap\.auto\.off {
1585    yylval.string = yytext;
1586    return LDAPAUTO;
1587 }
1588 
1589 ldap\.auth\.auto\.off {
1590    yylval.string = yytext;
1591    return LDAPAUTHAUTO;
1592 }
1593 
1594 ldap\.certcheck {
1595    yylval.string = yytext;
1596    return LDAPCERTCHECK;
1597 }
1598 
1599 ldap\.auth\.certcheck {
1600    yylval.string = yytext;
1601    return LDAPAUTHCERTCHECK;
1602 }
1603 
1604 ldap\.keeprealm {
1605    yylval.string = yytext;
1606    return LDAPKEEPREALM;
1607 }
1608 
1609 ldap\.filter {
1610        BEGIN(start_ldapfilter);
1611 
1612    yylval.string = yytext;
1613    return LDAPFILTER;
1614 }
1615 
1616 ldap\.auth\.filter {
1617        BEGIN(start_ldapfilter);
1618 
1619    yylval.string = yytext;
1620    return LDAPAUTHFILTER;
1621 }
1622 
1623 ldap\.filter\.ad {
1624        BEGIN(start_ldapfilter);
1625 
1626    yylval.string = yytext;
1627    return LDAPFILTER_AD;
1628 }
1629 
1630 ldap\.filter\.hex {
1631        BEGIN(start_ldapfilter);
1632 
1633    yylval.string = yytext;
1634    return LDAPFILTER_HEX;
1635 }
1636 
1637 ldap\.filter\.ad\.hex {
1638        BEGIN(start_ldapfilter);
1639 
1640    yylval.string = yytext;
1641    return LDAPFILTER_AD_HEX;
1642 }
1643 
1644 ldap\.attribute {
1645        BEGIN(start_ldapattribute);
1646 
1647    yylval.string = yytext;
1648    return LDAPATTRIBUTE;
1649 }
1650 
1651 ldap\.attribute\.ad {
1652        BEGIN(start_ldapattribute);
1653 
1654    yylval.string = yytext;
1655    return LDAPATTRIBUTE_AD;
1656 }
1657 
1658 ldap\.attribute\.hex {
1659        BEGIN(start_ldapattribute);
1660 
1661    yylval.string = yytext;
1662    return LDAPATTRIBUTE_HEX;
1663 }
1664 
1665 ldap\.attribute\.ad\.hex {
1666        BEGIN(start_ldapattribute);
1667 
1668    yylval.string = yytext;
1669    return LDAPATTRIBUTE_AD_HEX;
1670 }
1671 
1672 ldap\.server {
1673    BEGIN(start_ldapservername);
1674 
1675    yylval.string = yytext;
1676    return LDAPSERVER;
1677 }
1678 
1679 ldap\.auth\.server {
1680    BEGIN(start_ldapservername);
1681 
1682    yylval.string = yytext;
1683    return LDAPAUTHSERVER;
1684 }
1685 
1686 ldap\.group {
1687    BEGIN(start_ldapgroupname);
1688 
1689    yylval.string = yytext;
1690    return LDAPGROUP;
1691 }
1692 
1693 ldap\.group\.hex {
1694    BEGIN(start_ldapgroupname);
1695 
1696    yylval.string = yytext;
1697    return LDAPGROUP_HEX;
1698 }
1699 
1700 ldap\.group\.hex\.all {
1701    BEGIN(start_ldapgroupname);
1702 
1703    yylval.string = yytext;
1704    return LDAPGROUP_HEX_ALL;
1705 }
1706 
1707 ldap\.keytab {
1708    BEGIN(start_ldapkeytabname);
1709 
1710    yylval.string = yytext;
1711    return LDAPKEYTAB;
1712 }
1713 
1714 ldap\.auth\.keytab {
1715    BEGIN(start_ldapkeytabname);
1716 
1717    yylval.string = yytext;
1718    return LDAPAUTHKEYTAB;
1719 }
1720 
1721 pac\.sid\.b64 {
1722    BEGIN(start_pacsidname);
1723 
1724    yylval.string = yytext;
1725    return PACSID_B64;
1726 }
1727 
1728 pac\.sid {
1729    BEGIN(start_pacsidname);
1730 
1731    yylval.string = yytext;
1732    return PACSID;
1733 }
1734 
1735 pac\.off {
1736    yylval.string = yytext;
1737    return PACSID_FLAG;
1738 }
1739 
1740 bounce {
1741    yylval.string = yytext;
1742    return BOUNCE;
1743 }
1744 
1745 realm {
1746   BEGIN(start_realmname);
1747 
1748    yylval.string = yytext;
1749    return REALM;
1750 }
1751 
1752  /*
1753   * global keywords that are no longer used.
1754   */
1755 
1756 localdomain.*:.* {
1757    yywarnx_deprecated(yytext, NULL);
1758 }
1759 
1760 connecttimeout {
1761    yywarnx_deprecated(yytext, "timeout.connect");
1762 
1763    yylval.string = yytext;
1764    return CONNECTTIMEOUT;
1765 }
1766 
1767 iotimeout {
1768    yywarnx_deprecated(yytext, "timeout.io");
1769 
1770    yylval.string = yytext;
1771    return IOTIMEOUT;
1772 }
1773 
1774 socket.(recvbuf|sendbuf).(tcp|udp) {
1775    yylval.deprecated.oldname = yytext;
1776 
1777    yylval.deprecated.newname =
1778    "a general socket api.  E.g. \"internal.tcp.so_rcvbuf\" for setting "
1779    "the socket receive buffer size on the internal interface side, or "
1780    "\"external.tcp.so_sndbuf\" for setting the socket send buffer size on "
1781    "the external interface side.  Please see manual for more information";
1782 
1783    return DEPRECATED;
1784 }
1785 
1786 
1787    /* misc. generic stuff. */
1788 
1789    /*
1790     * note that to support negative numbers we need to handle number ranges
1791     * like port 1-65535 correctly also.
1792     */
1793 <*>([0-9]|0x[a-fA-F0-9])+ {
1794    char *ep;
1795    long long llval;
1796 
1797    errno  = 0;
1798    llval  = strtoll(yytext, &ep, 0);
1799    if (*yytext == NUL || *ep != NUL)
1800       yyerror("confusing.  Thought we would have a number here");
1801 
1802    if (errno == ERANGE)
1803       yyerror("number given is out of range");
1804 
1805    yylval.number = llval;
1806 
1807    if (shouldresetstate(YYSTATE, NUMBER))
1808       BEGIN(0);
1809 
1810    return NUMBER;
1811 }
1812 
1813    /* ignored */
1814 <*>[[:blank:]]+ {
1815    ;
1816 }
1817 
1818    /* shell style comment */
1819 <*>#.* {
1820    BEGIN(0);
1821    ;
1822 }
1823 
1824    /* state always ends at eol ... */
1825 <*>\n {
1826    BEGIN(0);
1827 }
1828 
1829    /* ... unless it's escaped. */
1830 <*>\\\n {
1831    ;
1832 }
1833 
1834 <*>\} {
1835    inclientrule = inroute = 0;
1836 
1837    yylval.string = yytext;
1838    return *yytext;
1839 }
1840 
1841 <*>. {
1842    yylval.string = yytext;
1843    return *yytext;
1844 }
1845 
1846 %%
1847 
1848 static int
1849 shouldresetstate(current_state, next_token)
1850    const int current_state;
1851    const int next_token;
1852 {
1853    switch (current_state) {
1854       case start_hostindex:
1855       case start_schedulemask:
1856       case start_servicename:
1857          switch (next_token) {
1858             case NUMBER:
1859                return 1;
1860          }
1861          break;
1862    }
1863 
1864    return 0;
1865 }
1866