Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / wiretap / ascend_scanner.l
blobba3a5e0dee0c58c3d5315049acafbcbc205385aa
1 %top {
2 /* Include this before everything else, for various large-file definitions */
3 #include "config.h"
4 #include <wireshark.h>
7 /*
8  * We want a reentrant scanner.
9  */
10 %option reentrant
13  * We don't read interactively from the terminal.
14  */
15 %option never-interactive
18  * We want to stop processing when we get to the end of the input.
19  */
20 %option noyywrap
23  * The type for the state we keep for the scanner (and parser).
24  */
25 %option extra-type="ascend_state_t *"
28  * Prefix scanner routines with "ascend_" rather than "yy", so this scanner
29  * can coexist with other scanners.
30  */
31 %option prefix="ascend_"
34  * We have to override the memory allocators so that we don't get
35  * "unused argument" warnings from the yyscanner argument (which
36  * we don't use, as we have a global memory allocator).
37  *
38  * We provide, as macros, our own versions of the routines generated by Flex,
39  * which just call malloc()/realloc()/free() (as the Flex versions do),
40  * discarding the extra argument.
41  */
42 %option noyyalloc
43 %option noyyrealloc
44 %option noyyfree
47 /* ascend_scanner.l
48  *
49  * Wiretap Library
50  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
51  *
52  * SPDX-License-Identifier: GPL-2.0-or-later
53  */
55 #include <stdlib.h>
56 #include <string.h>
58 #include "wtap-int.h"
59 #include "ascendtext.h"
60 #include "ascend-int.h"
61 #include "ascend_parser.h"
62 #include "file_wrappers.h"
65  * Disable diagnostics in the code generated by Flex.
66  */
67 DIAG_OFF_FLEX()
69 // The generated scanner is recursive if yywrap is enabled, but we disable it above.
70 // NOLINTBEGIN(misc-no-recursion)
72 static int ascend_yyinput(void *buf, ascend_state_t *parser_state) {
73     int c = file_getc(parser_state->fh);
74     if (c == EOF) {
75         parser_state->err = file_error(parser_state->fh,
76             &parser_state->err_info);
77         if (parser_state->err == 0)
78         parser_state->err = WTAP_ERR_SHORT_READ;
79         return YY_NULL;
80     } else {
81         *(char *) buf = c;
82         return 1;
83     }
86 #define YY_INPUT(buf, result, max_size) \
87   do { (result) = ascend_yyinput((buf), yyextra); } while (0)
90 /* Count bytes read. This is required in order to rewind the file
91  * to the beginning of the next packet, since flex reads more bytes
92  * before executing the action that does yyterminate(). */
93 #define YY_USER_ACTION do { yyextra->token.length = yyleng; } while (0);
95 #define NO_USER "<none>"
97 #ifndef HAVE_UNISTD_H
98 #define YY_NO_UNISTD_H
99 #endif
102  * Sleazy hack to suppress compiler warnings in yy_fatal_error().
103  */
104 #define YY_EXIT_FAILURE ((void)yyscanner, 2)
107  * Macros for the allocators, to discard the extra argument.
108  */
109 #define ascend_alloc(size, yyscanner)           (void *)malloc(size)
110 #define ascend_realloc(ptr, size, yyscanner)    (void *)realloc((char *)(ptr), (size))
111 #define ascend_free(ptr, yyscanner)             free((char *)ptr)
115 D [0-9]
116 H [A-Fa-f0-9]
118 PPP_XPFX PPP-OUT
119 PPP_RPFX PPP-IN
120 ISDN_XPFX PRI-XMIT-
121 ISDN_RPFX PRI-RCV-
122 WAN_XPFX XMIT[\-:]*
123 WAN_RPFX RECV[\-:]*
124 ETHER_PFX ETHER
126 WDD_DATE    "Date:"
127 WDD_TIME    "Time:"
128 WDD_CAUSE   "Cause an attempt to place call to "
129 WDD_CALLNUM [^\n\r\t ]+
130 WDD_CHUNK   "WD_DIALOUT_DISP: chunk"
131 WDD_TYPE    "type "[^\n\r\t ]+
133 %s sc_gen_task
134 %s sc_gen_time_s
135 %s sc_gen_time_u
136 %s sc_gen_octets
137 %s sc_gen_counter
138 %s sc_gen_byte
140 %s sc_wds_user
141 %s sc_wds_sess
143 %s sc_wdd_date_d
144 %s sc_wdd_date_m
145 %s sc_wdd_date_y
146 %s sc_wdd_time
147 %s sc_wdd_time_h
148 %s sc_wdd_time_m
149 %s sc_wdd_time_s
150 %s sc_wdd_cause
151 %s sc_wdd_callnum
152 %s sc_wdd_chunk
153 %s sc_wdd_chunknum
154 %s sc_wdd_type
156 %s sc_chardisp
158 %s sc_isdn_call
159 %s sc_ether_direction
163 <INITIAL,sc_gen_byte>{ETHER_PFX} {
164     BEGIN(sc_ether_direction);
165     yyextra->token.u16_val = ASCEND_PFX_ETHER;
166     return ETHER_PREFIX;
169 <INITIAL,sc_gen_byte>{ISDN_XPFX} {
170     BEGIN(sc_isdn_call);
171     yyextra->token.u16_val = ASCEND_PFX_ISDN_X;
172     return ISDN_PREFIX;
175 <INITIAL,sc_gen_byte>{ISDN_RPFX} {
176     BEGIN(sc_isdn_call);
177     yyextra->token.u16_val = ASCEND_PFX_ISDN_R;
178     return ISDN_PREFIX;
181 <INITIAL,sc_gen_byte>{WAN_XPFX} {
182     BEGIN(sc_wds_user);
183     yyextra->token.u16_val = ASCEND_PFX_WDS_X;
184     return WDS_PREFIX;
187 <INITIAL,sc_gen_byte>{WAN_RPFX} {
188     BEGIN(sc_wds_user);
189     yyextra->token.u16_val = ASCEND_PFX_WDS_R;
190     return WDS_PREFIX;
193 <INITIAL,sc_gen_byte>{PPP_XPFX} {
194     BEGIN(sc_wds_user);
195     yyextra->token.u16_val = ASCEND_PFX_WDS_X;
196     return WDS_PREFIX;
199 <INITIAL,sc_gen_byte>{PPP_RPFX} {
200     BEGIN(sc_wds_user);
201     yyextra->token.u16_val = ASCEND_PFX_WDS_R;
202     return WDS_PREFIX;
205  /*
206   * If we allow an arbitrary non-zero number of non-left-parentheses after
207   * "ETHER", that means that some file that has ETHER followed by a lot of
208   * text (see, for example, tpncp/tpncp.dat in the source tree) can cause
209   * either an infinite loop or a loop that take forever to finish, as the
210   * scanner keeps swallowing characters.  Limit it to 20 characters.
211   *
212   * XXX - any reason to require at least two of them?
213   */
214 <sc_ether_direction>[^\(]{2,20} {
215     BEGIN(sc_gen_task);
216     return STRING;
219  /*
220   * If we allow an arbitrary non-zero number of non-slash, non-left-parentheses,
221   * non-colon characters after "PRI-XMIT", that means that some file that has
222   * PRI-XMIT= followed by a lot of text can cause either an infinite loop or
223   * a loop that take forever to finish, as the scanner keeps swallowing
224   * characters.  Limit it to 20 characters.
225   */
226 <sc_isdn_call>[^\/\(:]{1,20} {
227     BEGIN(sc_gen_task);
228     return DECNUM;
231 <sc_wds_user>[^:]{2,20} {
232     char *atcopy = g_strdup(yytext);
233     char colon = input(yyscanner);
234     char after = input(yyscanner);
235     int retval = STRING;
237     unput(after); unput(colon);
239     if (after != '(' && after != ' ') {
240         BEGIN(sc_wds_sess);
241         if (yyextra->pseudo_header != NULL && yyextra->pseudo_header->user[0] == '\0') {
242         (void) g_strlcpy(yyextra->pseudo_header->user, atcopy, ASCEND_MAX_STR_LEN);
243         }
244     } else {    /* We have a version 7 file */
245         BEGIN(sc_gen_task);
246         if (yyextra->pseudo_header != NULL && yyextra->pseudo_header->user[0] == '\0') {
247         (void) g_strlcpy(yyextra->pseudo_header->user, NO_USER, ASCEND_MAX_STR_LEN);
248         }
249         /* Are valid values ever > 2^32? If so we need to adjust YYSTYPE and a lot of */
250         /* upstream code accordingly. */
251         yyextra->token.u32_val = (uint32_t) strtoul(yytext, NULL, 10);
252         retval = DECNUM;
253     }
254     g_free (atcopy);
255     return retval;
258 <sc_wds_sess>{D}* {
259     BEGIN(sc_gen_task);
260     yyextra->token.u32_val = (uint32_t) strtoul(yytext, NULL, 10);
261     return DECNUM;
264 <sc_gen_task>(0x|0X)?{H}{2,8} {
265     BEGIN(sc_gen_time_s);
266     yyextra->token.u32_val = (uint32_t) strtoul(yytext, NULL, 16);
267     return HEXNUM;
270 <sc_gen_task>\"[A-Za-z0-9_ ]+\" {
271     return STRING;
274 <sc_gen_time_s>{D}{1,10} {
275     BEGIN(sc_gen_time_u);
276     yyextra->token.u32_val = (uint32_t) strtoul(yytext, NULL, 10);
277     return DECNUM;
280 <sc_gen_time_u>{D}{1,6} {
281     char *atcopy = g_strdup(yytext);
282     BEGIN(sc_gen_octets);
283     /* only want the most significant 2 digits. convert to usecs */
284     if (strlen(atcopy) > 2)
285         atcopy[2] = '\0';
286     yyextra->token.u32_val = (uint32_t) strtoul(atcopy, NULL, 10) * 10000;
287     g_free(atcopy);
288     return DECNUM;
291 <sc_gen_octets>{D}{1,10} {
292     BEGIN(sc_gen_counter);
293     yyextra->token.u32_val = (uint32_t) strtoul(yytext, NULL, 10);
294     return DECNUM;
297 <sc_gen_counter,sc_gen_byte>"["{H}{4}"]:" {
298     BEGIN(sc_gen_byte);
299     return COUNTER;
302 <sc_gen_byte>{H}{2} {
303     yyextra->token.u8_val = (uint8_t) strtoul(yytext, NULL, 16);
304     return HEXBYTE;
307 <sc_gen_byte>" "{4} {
308     BEGIN(sc_chardisp);
311 <sc_chardisp>.* {
312     BEGIN(sc_gen_byte);
315 <INITIAL,sc_gen_byte>{WDD_DATE} {
316     BEGIN(sc_wdd_date_m);
317     return WDD_DATE;
320  /*
321   * Scan m/d/y as three separate m, /d/, and y tokens.
322   * We could alternately treat m/d/y as a single token.
323   */
324 <sc_wdd_date_m>{D}{2} {
325     BEGIN(sc_wdd_date_d);
326     yyextra->token.u32_val = (uint32_t) strtoul(yytext, NULL, 10);
327     return WDD_DECNUM;
330 <sc_wdd_date_d>\/{D}{2}\/ {
331     BEGIN(sc_wdd_date_y);
332     yyextra->token.u32_val = (uint32_t) strtoul(yytext+1, NULL, 10);
333     return WDD_DECNUM;
336 <sc_wdd_date_y>{D}{4} {
337     BEGIN(sc_wdd_time);
338     yyextra->token.u32_val = (uint32_t) strtoul(yytext, NULL, 10);
339     return WDD_DECNUM;
342 <sc_wdd_time>{WDD_TIME} {
343     BEGIN(sc_wdd_time_h);
344     return WDD_TIME;
347  /*
348   * Scan h:m:s as three separate h, :m:, and s tokens similar to above.
349   */
350 <sc_wdd_time_h>{D}{2} {
351     BEGIN(sc_wdd_time_m);
352     yyextra->token.u32_val = (uint32_t) strtoul(yytext, NULL, 10);
353     return WDD_DECNUM;
356 <sc_wdd_time_m>:{D}{2}: {
357     BEGIN(sc_wdd_time_s);
358     yyextra->token.u32_val = (uint32_t) strtoul(yytext+1, NULL, 10);
359     return WDD_DECNUM;
362 <sc_wdd_time_s>{D}{2} {
363     BEGIN(sc_wdd_cause);
364     yyextra->token.u32_val = (uint32_t) strtoul(yytext, NULL, 10);
365     return WDD_DECNUM;
368 <sc_wdd_cause>{WDD_CAUSE} {
369     BEGIN(sc_wdd_callnum);
370     return WDD_CAUSE;
373 <sc_wdd_callnum>{WDD_CALLNUM} {
374     BEGIN(sc_wdd_chunk);
375     (void) g_strlcpy(yyextra->token.str_val, yytext, ASCEND_MAX_STR_LEN);
376     return WDD_CALLNUM;
379 <INITIAL,sc_wdd_chunk,sc_gen_byte>{WDD_CHUNK} {
380     BEGIN(sc_wdd_chunknum);
381     return WDD_CHUNK;
384 <sc_wdd_chunknum>{H}{1,8} {
385     BEGIN(sc_wdd_type);
386     yyextra->token.u32_val = (uint32_t) strtoul(yytext, NULL, 16);
387     return HEXNUM;
390 <sc_wdd_type>{WDD_TYPE} {
391     BEGIN(sc_gen_task);
392     return KEYWORD;
395 <sc_gen_task>\/{D}+ {
396     return SLASH_SUFFIX;
399 (0x|0X)?{H}+ { return HEXNUM; }
401 task:|task|at|time:|octets { return KEYWORD; }
403 <<EOF>> { yyterminate(); }
405 (.|\n) ;
409 // NOLINTEND(misc-no-recursion)
412  * Turn diagnostics back on, so we check the code that we've written.
413  */
414 DIAG_ON_FLEX()