forked from osmocom/wireshark
199 lines
6.9 KiB
Plaintext
199 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"
|
|
}
|
|
|
|
%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
|