wireshark/wiretap/busmaster_scanner.l

200 lines
6.9 KiB
Plaintext

/* busmaster_scanner.l
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
*
* Support for Busmaster log file format
* Copyright (c) 2019 by Maksim Salau <maksim.salau@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
%top {
/* Include this before everything else, for various large-file definitions */
#include "config.h"
#include <wireshark.h>
}
%option noyywrap
%option noinput
%option nounput
%option batch
%option never-interactive
%option nodefault
%option prefix="busmaster_"
%option reentrant
%option extra-type="busmaster_state_t *"
%option noyy_scan_buffer
%option noyy_scan_bytes
%option noyy_scan_string
/*
* We have to override the memory allocators so that we don't get
* "unused argument" warnings from the yyscanner argument (which
* we don't use, as we have a global memory allocator).
*
* We provide, as macros, our own versions of the routines generated by Flex,
* which just call malloc()/realloc()/free() (as the Flex versions do),
* discarding the extra argument.
*/
%option noyyalloc
%option noyyrealloc
%option noyyfree
%{
#include <ws_diag_control.h>
#include <wiretap/file_wrappers.h>
#include "busmaster_parser.h"
#include "busmaster_priv.h"
#ifndef HAVE_UNISTD_H
#define YY_NO_UNISTD_H
#endif
static int busmaster_yyinput(void *buf, unsigned int length, busmaster_state_t *state)
{
int ret = file_read(buf, length, state->fh);
if (ret < 0)
{
state->err = file_error(state->fh, &state->err_info);
return YY_NULL;
}
return ret;
}
#define YY_INPUT(buf, result, max_size) \
do { (result) = busmaster_yyinput((buf), (max_size), yyextra); } while (0)
/* Count bytes read. This is required in order to rewind the file
* to the beginning of the next packet, since flex reads more bytes
* before executing the action that does yyterminate(). */
#define YY_USER_ACTION do { yyextra->file_bytes_read += yyleng; } while (0);
/*
* Sleazy hack to suppress compiler warnings in yy_fatal_error().
*/
#define YY_EXIT_FAILURE ((void)yyscanner, 2)
/*
* Macros for the allocators, to discard the extra argument.
*/
#define busmaster_alloc(size, yyscanner) (void *)malloc(size)
#define busmaster_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
#define busmaster_free(ptr, yyscanner) free((char *)(ptr))
DIAG_OFF_FLEX()
%}
SPC [ \t]+
ENDL [\r\n][ \t\r\n]*
INT [0-9]+
NUM (0x)?[0-9A-Fa-f]+
%x HEADER TIME
%x HEADER_CHANNELS HEADER_DB_FILES
%%
<*>{SPC} ;
<INITIAL>{ENDL} { yyterminate(); };
<HEADER,TIME>{ENDL} { YY_FATAL_ERROR("Unterminated header statement"); }
"***" { BEGIN(HEADER); }
<HEADER,TIME>"***"{ENDL}"***" { BEGIN(HEADER); return TOKEN_ENDL; }
<HEADER>"***"{ENDL} { BEGIN(INITIAL); yyterminate(); }
<HEADER>"BUSMASTER" { return TOKEN_HEADER_VER; }
<HEADER>"PROTOCOL CAN" { yyextra->token.v0 = PROTOCOL_CAN; return TOKEN_PROTOCOL_TYPE; }
<HEADER>"PROTOCOL J1939" { yyextra->token.v0 = PROTOCOL_J1939; return TOKEN_PROTOCOL_TYPE; }
<HEADER>"PROTOCOL LIN" { yyextra->token.v0 = PROTOCOL_LIN; return TOKEN_PROTOCOL_TYPE; }
<HEADER>"START DATE AND TIME" { BEGIN(TIME); return TOKEN_START_TIME; }
<HEADER>"END DATE AND TIME" { BEGIN(TIME); return TOKEN_END_TIME; }
<HEADER>"DEC" { yyextra->token.v0 = DATA_MODE_DEC; return TOKEN_DATA_MODE; }
<HEADER>"HEX" { yyextra->token.v0 = DATA_MODE_HEX; return TOKEN_DATA_MODE; }
<HEADER>"ABSOLUTE MODE" { yyextra->token.v0 = TIME_MODE_ABSOLUTE; return TOKEN_TIME_MODE; }
<HEADER>"SYSTEM MODE" { yyextra->token.v0 = TIME_MODE_SYSTEM; return TOKEN_TIME_MODE; }
<HEADER>"RELATIVE MODE" { yyextra->token.v0 = TIME_MODE_RELATIVE; return TOKEN_TIME_MODE; }
<HEADER>"[START LOGGING SESSION]" { return TOKEN_START_SESSION; }
<HEADER>"[STOP LOGGING SESSION]" { return TOKEN_STOP_SESSION; }
<HEADER>"START CHANNEL BAUD RATE***" { BEGIN(HEADER_CHANNELS); }
<HEADER>"START DATABASE FILES (DBF/DBC)***" { BEGIN(HEADER_DB_FILES); }
<HEADER>. { return TOKEN_HEADER_CHAR; }
<HEADER_CHANNELS>"***END CHANNEL BAUD RATE***"{ENDL}"***" { BEGIN(HEADER); }
<HEADER_CHANNELS>.+ ;
<HEADER_CHANNELS>{ENDL} ;
<HEADER_DB_FILES>"***END DATABASE FILES (DBF/DBC)***"{ENDL}"***" { BEGIN(HEADER); }
<HEADER_DB_FILES>"***END OF DATABASE FILES (DBF/DBC)***"{ENDL}"***" { BEGIN(HEADER); }
<HEADER_DB_FILES>.+ ;
<HEADER_DB_FILES>{ENDL} ;
<TIME>{INT} { yyextra->token.v0 = strtoul(yytext, NULL, 10); return TOKEN_INT; }
<TIME>: { return TOKEN_COLON; }
<TIME>. { return TOKEN_INVALID_CHAR; }
<INITIAL>{INT}:{INT}:{INT}:{INT} {
char *endp;
char *strp;
yyextra->token.v0 = strtoul(yytext, &endp, 10);
if (*endp != ':' || endp == yytext)
return TOKEN_INVALID_NUMBER;
strp = endp + 1;
yyextra->token.v1 = strtoul(strp, &endp, 10);
if (*endp != ':' || endp == strp)
return TOKEN_INVALID_NUMBER;
strp = endp + 1;
yyextra->token.v2 = strtoul(strp, &endp, 10);
if (*endp != ':' || endp == strp)
return TOKEN_INVALID_NUMBER;
strp = endp + 1;
yyextra->token.v3 = strtoul(strp, &endp, 10);
if (*endp != '\0' || endp == strp)
return TOKEN_INVALID_NUMBER;
return TOKEN_MSG_TIME;
}
<INITIAL>{NUM} {
char *endp;
if (yyextra->header.data_mode == DATA_MODE_HEX)
yyextra->token.v0 = strtoul(yytext, &endp, 16);
else if (yyextra->header.data_mode == DATA_MODE_DEC)
yyextra->token.v0 = strtoul(yytext, &endp, 10);
else
return TOKEN_INVALID_NUMBER;
if (*endp != '\0' || endp == yytext)
return TOKEN_INVALID_NUMBER;
return TOKEN_INT;
}
<INITIAL>[RT]x { return TOKEN_MSG_DIR; }
<INITIAL>s { yyextra->token.v0 = MSG_TYPE_STD; return TOKEN_MSG_TYPE; }
<INITIAL>sr { yyextra->token.v0 = MSG_TYPE_STD_RTR; return TOKEN_MSG_TYPE; }
<INITIAL>x { yyextra->token.v0 = MSG_TYPE_EXT; return TOKEN_MSG_TYPE; }
<INITIAL>xr { yyextra->token.v0 = MSG_TYPE_EXT_RTR; return TOKEN_MSG_TYPE; }
<INITIAL>s-fd { yyextra->token.v0 = MSG_TYPE_STD_FD; return TOKEN_MSG_TYPE; }
<INITIAL>x-fd { yyextra->token.v0 = MSG_TYPE_EXT_FD; return TOKEN_MSG_TYPE; }
<INITIAL>ERR.* { yyextra->token.v0 = MSG_TYPE_ERR; return TOKEN_ERR_MSG_TYPE; }
<INITIAL>("NONE"|"CMD"|"RQST"|"DATA"|"BROADCAST"|"ACK"|"GRP_FUNC"|"ACL"|"RQST_ACL"|"CA"|"BAM"|"RTS"|"CTS"|"EOM"|"CON_ABORT"|"TPDT") {
return TOKEN_J1939_MSG_TYPE;
}
<INITIAL>. { return TOKEN_INVALID_CHAR; }
%%
DIAG_ON_FLEX()