/* * We want a reentrant scanner. */ %option reentrant /* * We want to generate code that can be used by a reentrant parser * generated by Bison or Berkeley YACC. */ %option bison-bridge /* * We don't read interactively from the terminal. */ %option never-interactive /* * We want to stop processing when we get to the end of the input. */ %option noyywrap /* * The type for the state we keep for the scanner (and parser). */ %option extra-type="ascend_state_t *" /* * Prefix scanner routines with "ascend" rather than "yy", so this scanner * can coexist with other scanners. */ %option prefix="ascend" /* * 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 %{ /* ascend_scanner.l * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include #include #include "wtap-int.h" #include "ascendtext.h" #include "ascend-int.h" #include "ascend.h" #include "file_wrappers.h" #define YY_INPUT(buf,result,max_size) { \ ascend_state_t *parser_state = ascendget_extra(yyscanner); \ int c = file_getc(parser_state->fh); \ if (c == EOF) { \ *(parser_state->err) = file_error(parser_state->fh, \ parser_state->err_info); \ if (*(parser_state->err) == 0) \ *(parser_state->err) = WTAP_ERR_SHORT_READ; \ result = YY_NULL; \ } else { \ buf[0] = c; \ result = 1; \ } \ } #define NO_USER "" #ifndef HAVE_UNISTD_H #define YY_NO_UNISTD_H #endif /* * 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 ascendalloc(size, yyscanner) (void *)malloc(size) #define ascendrealloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size)) #define ascendfree(ptr, yyscanner) free((char *)ptr) %} D [0-9] H [A-Fa-f0-9] PPP_XPFX PPP-OUT PPP_RPFX PPP-IN ISDN_XPFX PRI-XMIT- ISDN_RPFX PRI-RCV- WAN_XPFX XMIT[\-:]* WAN_RPFX RECV[\-:]* ETHER_PFX ETHER WDD_DATE "Date:" WDD_TIME "Time:" WDD_CAUSE "Cause an attempt to place call to " WDD_CALLNUM [^\n\r\t ]+ WDD_CHUNK "WD_DIALOUT_DISP: chunk" WDD_TYPE "type "[^\n\r\t ]+ %s sc_gen_task %s sc_gen_time_s %s sc_gen_time_u %s sc_gen_octets %s sc_gen_counter %s sc_gen_byte %s sc_wds_user %s sc_wds_sess %s sc_wdd_date_d %s sc_wdd_date_m %s sc_wdd_date_y %s sc_wdd_time %s sc_wdd_time_h %s sc_wdd_time_m %s sc_wdd_time_s %s sc_wdd_cause %s sc_wdd_callnum %s sc_wdd_chunk %s sc_wdd_chunknum %s sc_wdd_type %s sc_chardisp %s sc_isdn_call %s sc_ether_direction %% {ETHER_PFX} { BEGIN(sc_ether_direction); yylval->d = ASCEND_PFX_ETHER; return ETHER_PREFIX; } {ISDN_XPFX} { BEGIN(sc_isdn_call); yylval->d = ASCEND_PFX_ISDN_X; return ISDN_PREFIX; } {ISDN_RPFX} { BEGIN(sc_isdn_call); yylval->d = ASCEND_PFX_ISDN_R; return ISDN_PREFIX; } {WAN_XPFX} { BEGIN(sc_wds_user); yylval->d = ASCEND_PFX_WDS_X; return WDS_PREFIX; } {WAN_RPFX} { BEGIN(sc_wds_user); yylval->d = ASCEND_PFX_WDS_R; return WDS_PREFIX; } {PPP_XPFX} { BEGIN(sc_wds_user); yylval->d = ASCEND_PFX_WDS_X; return WDS_PREFIX; } {PPP_RPFX} { BEGIN(sc_wds_user); yylval->d = ASCEND_PFX_WDS_R; return WDS_PREFIX; } [^\(]{2,20} { BEGIN(sc_gen_task); return STRING; } [^\/\(:]{2,20} { BEGIN(sc_gen_task); return DECNUM; } [^:]{2,20} { char *atcopy = g_strdup(yytext); char colon = input(yyscanner); char after = input(yyscanner); int retval = STRING; unput(after); unput(colon); if (after != '(' && after != ' ') { BEGIN(sc_wds_sess); if (yyextra->pseudo_header != NULL) { g_strlcpy(yyextra->pseudo_header->user, atcopy, ASCEND_MAX_STR_LEN); } } else { /* We have a version 7 file */ BEGIN(sc_gen_task); if (yyextra->pseudo_header != NULL) { g_strlcpy(yyextra->pseudo_header->user, NO_USER, ASCEND_MAX_STR_LEN); } /* Are valid values ever > 2^32? If so we need to adjust YYSTYPE and a lot of */ /* upstream code accordingly. */ yylval->d = (guint32) strtoul(yytext, NULL, 10); retval = DECNUM; } g_free (atcopy); return retval; } {D}* { BEGIN(sc_gen_task); yylval->d = (guint32) strtoul(yytext, NULL, 10); return DECNUM; } (0x|0X)?{H}{2,8} { BEGIN(sc_gen_time_s); yylval->d = (guint32) strtoul(yytext, NULL, 16); return HEXNUM; } \"[A-Za-z0-9_ ]+\" { return STRING; } {D}{1,10} { BEGIN(sc_gen_time_u); yylval->d = (guint32) strtoul(yytext, NULL, 10); return DECNUM; } {D}{1,6} { char *atcopy = g_strdup(yytext); BEGIN(sc_gen_octets); /* only want the most significant 2 digits. convert to usecs */ if (strlen(atcopy) > 2) atcopy[2] = '\0'; yylval->d = (guint32) strtoul(atcopy, NULL, 10) * 10000; g_free(atcopy); return DECNUM; } {D}{1,10} { BEGIN(sc_gen_counter); yylval->d = (guint32) strtoul(yytext, NULL, 10); return DECNUM; } "["{H}{4}"]:" { BEGIN(sc_gen_byte); return COUNTER; } {H}{2} { yylval->b = (guint8)(guint32) strtoul(yytext, NULL, 16); return HEXBYTE; } " "{4} { BEGIN(sc_chardisp); } .* { BEGIN(sc_gen_byte); } {WDD_DATE} { BEGIN(sc_wdd_date_d); return WDD_DATE; } {D}{2} { BEGIN(sc_wdd_date_m); yylval->d = (guint32) strtoul(yytext, NULL, 10); return DECNUM; } {D}{2} { BEGIN(sc_wdd_date_y); yylval->d = (guint32) strtoul(yytext, NULL, 10); return DECNUM; } {D}{4} { BEGIN(sc_wdd_time); yylval->d = (guint32) strtoul(yytext, NULL, 10); return DECNUM; } {WDD_TIME} { BEGIN(sc_wdd_time_h); return KEYWORD; } {D}{2} { BEGIN(sc_wdd_time_m); yylval->d = (guint32) strtoul(yytext, NULL, 10); return DECNUM; } {D}{2} { BEGIN(sc_wdd_time_s); yylval->d = (guint32) strtoul(yytext, NULL, 10); return DECNUM; } {D}{2} { BEGIN(sc_wdd_cause); yylval->d = (guint32) strtoul(yytext, NULL, 10); return DECNUM; } {WDD_CAUSE} { BEGIN(sc_wdd_callnum); return KEYWORD; } {WDD_CALLNUM} { BEGIN(sc_wdd_chunk); if (yyextra->pseudo_header != NULL) { g_strlcpy(yyextra->pseudo_header->call_num, yytext, ASCEND_MAX_STR_LEN); } return STRING; } {WDD_CHUNK} { BEGIN(sc_wdd_chunknum); return WDD_CHUNK; } {H}{1,8} { BEGIN(sc_wdd_type); yylval->d = (guint32) strtoul(yytext, NULL, 16); return HEXNUM; } {WDD_TYPE} { BEGIN(sc_gen_task); return KEYWORD; } \/{D}+ { return SLASH_SUFFIX; } (0x|0X)?{H}+ { return HEXNUM; } task:|task|at|time:|octets { return KEYWORD; } <> { yyterminate(); } (.|\n) ;