4 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
6 * Support for Busmaster log file format
7 * Copyright (c) 2019 by Maksim Salau <maksim.salau@gmail.com>
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 /* Include this before everything else, for various large-file definitions */
15 #include <wireshark.h>
22 %option never-interactive
24 %option prefix="busmaster_"
26 %option extra-type="busmaster_state_t *"
28 %option noyy_scan_buffer
29 %option noyy_scan_bytes
30 %option noyy_scan_string
33 * We have to override the memory allocators so that we don't get
34 * "unused argument" warnings from the yyscanner argument (which
35 * we don't use, as we have a global memory allocator).
37 * We provide, as macros, our own versions of the routines generated by Flex,
38 * which just call malloc()/realloc()/free() (as the Flex versions do),
39 * discarding the extra argument.
47 #include <ws_diag_control.h>
48 #include <wiretap/file_wrappers.h>
49 #include "busmaster_parser.h"
50 #include "busmaster_priv.h"
53 #define YY_NO_UNISTD_H
56 static int busmaster_yyinput(void *buf, unsigned int length, busmaster_state_t *state)
58 int ret = file_read(buf, length, state->fh);
62 state->err = file_error(state->fh, &state->err_info);
69 #define YY_INPUT(buf, result, max_size) \
70 do { (result) = busmaster_yyinput((buf), (max_size), yyextra); } while (0)
72 /* Count bytes read. This is required in order to rewind the file
73 * to the beginning of the next packet, since flex reads more bytes
74 * before executing the action that does yyterminate(). */
75 #define YY_USER_ACTION do { yyextra->file_bytes_read += yyleng; } while (0);
78 * Sleazy hack to suppress compiler warnings in yy_fatal_error().
80 #define YY_EXIT_FAILURE ((void)yyscanner, 2)
83 * Macros for the allocators, to discard the extra argument.
85 #define busmaster_alloc(size, yyscanner) (void *)malloc(size)
86 #define busmaster_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
87 #define busmaster_free(ptr, yyscanner) free((char *)(ptr))
99 %x HEADER_CHANNELS HEADER_DB_FILES
104 <INITIAL>{ENDL} { yyterminate(); };
105 <HEADER,TIME>{ENDL} { YY_FATAL_ERROR("Unterminated header statement"); }
107 "***" { BEGIN(HEADER); }
108 <HEADER,TIME>"***"{ENDL}"***" { BEGIN(HEADER); return TOKEN_ENDL; }
109 <HEADER>"***"{ENDL} { BEGIN(INITIAL); yyterminate(); }
110 <HEADER>"BUSMASTER" { return TOKEN_HEADER_VER; }
111 <HEADER>"PROTOCOL CAN" { yyextra->token.v0 = PROTOCOL_CAN; return TOKEN_PROTOCOL_TYPE; }
112 <HEADER>"PROTOCOL J1939" { yyextra->token.v0 = PROTOCOL_J1939; return TOKEN_PROTOCOL_TYPE; }
113 <HEADER>"PROTOCOL LIN" { yyextra->token.v0 = PROTOCOL_LIN; return TOKEN_PROTOCOL_TYPE; }
114 <HEADER>"START DATE AND TIME" { BEGIN(TIME); return TOKEN_START_TIME; }
115 <HEADER>"END DATE AND TIME" { BEGIN(TIME); return TOKEN_END_TIME; }
116 <HEADER>"DEC" { yyextra->token.v0 = DATA_MODE_DEC; return TOKEN_DATA_MODE; }
117 <HEADER>"HEX" { yyextra->token.v0 = DATA_MODE_HEX; return TOKEN_DATA_MODE; }
118 <HEADER>"ABSOLUTE MODE" { yyextra->token.v0 = TIME_MODE_ABSOLUTE; return TOKEN_TIME_MODE; }
119 <HEADER>"SYSTEM MODE" { yyextra->token.v0 = TIME_MODE_SYSTEM; return TOKEN_TIME_MODE; }
120 <HEADER>"RELATIVE MODE" { yyextra->token.v0 = TIME_MODE_RELATIVE; return TOKEN_TIME_MODE; }
121 <HEADER>"[START LOGGING SESSION]" { return TOKEN_START_SESSION; }
122 <HEADER>"[STOP LOGGING SESSION]" { return TOKEN_STOP_SESSION; }
123 <HEADER>"START CHANNEL BAUD RATE***" { BEGIN(HEADER_CHANNELS); }
124 <HEADER>"START DATABASE FILES (DBF/DBC)***" { BEGIN(HEADER_DB_FILES); }
125 <HEADER>. { return TOKEN_HEADER_CHAR; }
127 <HEADER_CHANNELS>"***END CHANNEL BAUD RATE***"{ENDL}"***" { BEGIN(HEADER); }
128 <HEADER_CHANNELS>.+ ;
129 <HEADER_CHANNELS>{ENDL} ;
131 <HEADER_DB_FILES>"***END DATABASE FILES (DBF/DBC)***"{ENDL}"***" { BEGIN(HEADER); }
132 <HEADER_DB_FILES>"***END OF DATABASE FILES (DBF/DBC)***"{ENDL}"***" { BEGIN(HEADER); }
133 <HEADER_DB_FILES>.+ ;
134 <HEADER_DB_FILES>{ENDL} ;
136 <TIME>{INT} { yyextra->token.v0 = strtoul(yytext, NULL, 10); return TOKEN_INT; }
137 <TIME>: { return TOKEN_COLON; }
138 <TIME>. { return TOKEN_INVALID_CHAR; }
140 <INITIAL>{INT}:{INT}:{INT}:{INT} {
144 yyextra->token.v0 = strtoul(yytext, &endp, 10);
145 if (*endp != ':' || endp == yytext)
146 return TOKEN_INVALID_NUMBER;
149 yyextra->token.v1 = strtoul(strp, &endp, 10);
150 if (*endp != ':' || endp == strp)
151 return TOKEN_INVALID_NUMBER;
154 yyextra->token.v2 = strtoul(strp, &endp, 10);
155 if (*endp != ':' || endp == strp)
156 return TOKEN_INVALID_NUMBER;
159 yyextra->token.v3 = strtoul(strp, &endp, 10);
160 if (*endp != '\0' || endp == strp)
161 return TOKEN_INVALID_NUMBER;
163 return TOKEN_MSG_TIME;
169 if (yyextra->header.data_mode == DATA_MODE_HEX)
170 yyextra->token.v0 = strtoul(yytext, &endp, 16);
171 else if (yyextra->header.data_mode == DATA_MODE_DEC)
172 yyextra->token.v0 = strtoul(yytext, &endp, 10);
174 return TOKEN_INVALID_NUMBER;
176 if (*endp != '\0' || endp == yytext)
177 return TOKEN_INVALID_NUMBER;
182 <INITIAL>[RT]x { return TOKEN_MSG_DIR; }
183 <INITIAL>s { yyextra->token.v0 = MSG_TYPE_STD; return TOKEN_MSG_TYPE; }
184 <INITIAL>sr { yyextra->token.v0 = MSG_TYPE_STD_RTR; return TOKEN_MSG_TYPE; }
185 <INITIAL>x { yyextra->token.v0 = MSG_TYPE_EXT; return TOKEN_MSG_TYPE; }
186 <INITIAL>xr { yyextra->token.v0 = MSG_TYPE_EXT_RTR; return TOKEN_MSG_TYPE; }
187 <INITIAL>s-fd { yyextra->token.v0 = MSG_TYPE_STD_FD; return TOKEN_MSG_TYPE; }
188 <INITIAL>x-fd { yyextra->token.v0 = MSG_TYPE_EXT_FD; return TOKEN_MSG_TYPE; }
189 <INITIAL>ERR.* { yyextra->token.v0 = MSG_TYPE_ERR; return TOKEN_ERR_MSG_TYPE; }
191 <INITIAL>("NONE"|"CMD"|"RQST"|"DATA"|"BROADCAST"|"ACK"|"GRP_FUNC"|"ACL"|"RQST_ACL"|"CA"|"BAM"|"RTS"|"CTS"|"EOM"|"CON_ABORT"|"TPDT") {
192 return TOKEN_J1939_MSG_TYPE;
195 <INITIAL>. { return TOKEN_INVALID_CHAR; }