2 * We don't use unput, so don't generate code for it.
7 * We don't read from the terminal.
9 %option never-interactive
12 * Prefix scanner routines with "K12Text_" rather than "yy", so this scanner
13 * can coexist with other scanners.
15 %option prefix="K12Text_"
17 %option outfile="k12text.c"
19 /* Options useful for debugging */
20 /* noline: Prevent generation of #line directives */
21 /* Seems to be required when using the */
22 /* Windows VS debugger so as to be able */
23 /* to properly step through the code and */
24 /* set breakpoints & etc using the */
25 /* k12text.c file rather than the */
27 /* XXX: %option noline gives an error message: */
28 /* "unrecognized %option: line" */
29 /* with flex 2.5.35; the --noline */
30 /* command-line option works OK. */
32 /* debug: Do output of "rule acceptance" info */
44 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
46 * This program is free software; you can redistribute it and/or
47 * modify it under the terms of the GNU General Public License
48 * as published by the Free Software Foundation; either version 2
49 * of the License, or (at your option) any later version.
51 * This program is distributed in the hope that it will be useful,
52 * but WITHOUT ANY WARRANTY; without even the implied warranty of
53 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54 * GNU General Public License for more details.
56 * You should have received a copy of the GNU General Public License
57 * along with this program; if not, write to the Free Software
58 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
63 * - fix timestamps after midnight
64 * - verify encapsulations
76 #include "file_wrappers.h"
79 #include "k12text_lex.h"
82 #define YY_NO_UNISTD_H
91 static guint8 bb[WTAP_MAX_PACKET_SIZE];
93 static gboolean is_k12text;
94 static gboolean at_eof;
95 static guint junk_chars;
96 static void finalize_frame(void);
97 static gchar* error_str;
98 static guint file_bytes_read;
99 static gboolean ok_frame;
102 #define KERROR(text) do { error_str = g_strdup(text); yyterminate(); } while(0)
103 #define SET_HOURS(text) g_h = strtoul(text,NULL,10)
104 #define SET_MINUTES(text) g_m = strtoul(text,NULL,10)
105 #define SET_SECONDS(text) g_s = strtoul(text,NULL,10)
106 #define SET_MS(text) g_ms = strtoul(text,NULL,10)
107 #define SET_NS(text) g_ns = strtoul(text,NULL,10)
108 #define ADD_BYTE(text) do {if (ii >= WTAP_MAX_PACKET_SIZE) {KERROR("frame too large");} bb[ii++] = (guint8)strtoul(text,NULL,16); } while(0)
109 #define FINALIZE_FRAME() finalize_frame()
111 #define YY_USER_ACTION file_bytes_read += yyleng;
112 #define YY_INPUT(buf,result,max_size) { int c = file_getc(yy_fh); result = (c==EOF) ? YY_NULL : (buf[0] = c, 1); }
114 #define MAX_JUNK 400000
117 start_timestamp \053[\055]{9}\053[\055]{15,100}\053[\055]{10,100}\053
118 oneormoredigits [0-9]+:
122 threedigits [0-9][0-9][0-9]
123 start_bytes \174\060\040\040\040\174
124 bytes_junk \174[A-F0-9][A-F0-9\040][A-F0-9\040][A-F0-9\040]\174
125 byte [a-f0-9][a-f0-9]\174
126 end_bytes \015?\012\015?\012
128 /* mtp2 MTP-L2 ;; XXX: Not supported until it's determined how to fill in the pseudo_header req'd by packet-mtp2 */
129 /* sscop SSCOP ;; XXX: Not supported until it's determined how to fill in the pseudo_header req'd by packet-atm */
133 %START MAGIC NEXT_FRAME HOURS MINUTES M2S SECONDS S2M MS M2N NS ENCAP STARTBYTES BYTE
135 <MAGIC>{start_timestamp} { is_k12text = TRUE; yyterminate(); }
137 <MAGIC>. { if (++ junk_chars > MAX_JUNK) { is_k12text = FALSE; yyterminate(); } }
139 <NEXT_FRAME>{start_timestamp} {BEGIN(HOURS); }
140 <HOURS>{oneormoredigits} { SET_HOURS(yytext); BEGIN(MINUTES); }
141 <MINUTES>{twodigits} { SET_MINUTES(yytext); BEGIN(M2S);}
142 <M2S>{colon} { BEGIN(SECONDS);}
143 <SECONDS>{twodigits} { SET_SECONDS(yytext); BEGIN(S2M); }
144 <S2M>{comma} { BEGIN(MS); }
145 <MS>{threedigits} { SET_MS(yytext); BEGIN(M2N); }
146 <M2N>{comma} { BEGIN(NS); }
147 <NS>{threedigits} { SET_NS(yytext); BEGIN(ENCAP);}
148 <ENCAP>{eth} {g_encap = WTAP_ENCAP_ETHERNET; BEGIN(STARTBYTES); }
149 /* <ENCAP>{mtp2} {g_encap = WTAP_ENCAP_MTP2; BEGIN(STARTBYTES); } Not supported as yet */
150 /* <ENCAP>{sscop} {g_encap = WTAP_ENCAP_ATM_PDUS; BEGIN(STARTBYTES); } Not supported as yet */
151 <ENCAP>{sscfnni} {g_encap = WTAP_ENCAP_MTP3; BEGIN(STARTBYTES); }
152 <ENCAP>{hdlc} {g_encap = WTAP_ENCAP_CHDLC; BEGIN(STARTBYTES); }
153 <ENCAP,STARTBYTES>{start_bytes} { BEGIN(BYTE); }
154 <BYTE>{byte} { ADD_BYTE(yytext); }
156 <BYTE>{end_bytes} { FINALIZE_FRAME(); yyterminate(); }
158 . { if (++junk_chars > MAX_JUNK) { KERROR("too much junk"); } }
159 <<EOF>> { at_eof = TRUE; yyterminate(); }
163 static void finalize_frame(void) {
167 /* Fill in pseudo-header according to the encapsulation type */
169 static void k12text_set_pseudo_header(wtap *wth, union wtap_pseudo_header *pseudo_header) {
170 /* The file-encap is WTAP_ENCAP_PER_PACKET */
171 switch(wth->phdr.pkt_encap) {
172 case WTAP_ENCAP_ETHERNET:
173 pseudo_header->eth.fcs_len = 0;
175 case WTAP_ENCAP_MTP3:
176 case WTAP_ENCAP_CHDLC:
177 /* no pseudo_header to fill in for these types */
180 case WTAP_ENCAP_MTP2: /* not (yet) supported */
181 case WTAP_ENCAP_ATM_PDUS: /* not (yet) supported */
182 /* XXX: I don't know how to fill in the */
183 /* pseudo_header for these types. So: The Lexer */
184 /* has recognition for these types commented */
188 case WTAP_ENCAP_UNKNOWN:
194 /* Note: k12text_reset is called each time data is to be processed from */
195 /* a file. This ensures that no "state" from a previous read is */
196 /* used (such as the lexer look-ahead buffer, file_handle, file */
197 /* position and so on. This allows a single lexer buffer to be */
198 /* used even when multiple files are open simultaneously (as for */
201 static void k12text_reset(FILE_T fh) {
204 g_encap = WTAP_ENCAP_UNKNOWN;
219 static gboolean k12text_read(wtap *wth, int *err, char ** err_info, gint64 *data_offset) {
221 /* We seek to the file position after the end of the previous frame processed by */
222 /* k12text_read (kept in wth->data_offset). We do this each time since the lexer */
223 /* undoubtedly did some amount of look-ahead when processing the previous frame. */
224 /* We also clear out any lexer state (eg: look-ahead buffer) and init vars set by lexer. */
226 if ( file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
229 k12text_reset(wth->fh); /* init lexer buffer and vars set by lexer */
234 if (ok_frame == FALSE) {
239 *err = WTAP_ERR_BAD_RECORD;
240 *err_info = error_str;
245 *data_offset = wth->data_offset; /* file position for beginning of this frame */
246 wth->data_offset += file_bytes_read; /* file position after end of this frame */
248 wth->phdr.ts.secs = 946681200 + (3600*g_h) + (60*g_m) + g_s;
249 wth->phdr.ts.nsecs = 1000000*g_ms + 1000*g_ns;
251 wth->phdr.caplen = wth->phdr.len = ii;
253 wth->phdr.pkt_encap = g_encap;
254 k12text_set_pseudo_header(wth, &wth->pseudo_header);
256 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
257 memcpy(buffer_start_ptr(wth->frame_buffer), bb, wth->phdr.caplen);
262 static gboolean k12text_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header *pseudo_header, guint8 *pd, int length, int *err, char **err_info) {
264 if ( file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) {
267 k12text_reset(wth->random_fh); /* init lexer buffer and vars set by lexer */
272 if (ok_frame == FALSE) {
273 *err = WTAP_ERR_BAD_RECORD;
275 /* What happened ? The desired frame was previously read without a problem */
276 *err_info = g_strdup("Unexpected EOF (program error ?)");
278 *err_info = error_str;
283 /* verify frame length parsed this time against original frame length */
284 if (ii != (guint)length) {
285 /* What happened ? This now seems to have a different length than originally */
286 *err = WTAP_ERR_BAD_RECORD;
287 *err_info = g_strdup("Incorrect frame length (program error ?)");
291 k12text_set_pseudo_header(wth, pseudo_header);
293 memcpy(pd, bb, length);
298 int k12text_open(wtap *wth, int *err, gchar **err_info _U_) {
300 k12text_reset(wth->fh); /* init lexer buffer and vars set by lexer */
305 if (! is_k12text) return 0;
307 if ( file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
311 wth->data_offset = 0;
312 wth->file_type = WTAP_FILE_K12TEXT;
313 wth->file_encap = WTAP_ENCAP_PER_PACKET;
314 wth->snapshot_length = 0;
315 wth->subtype_read = k12text_read;
316 wth->subtype_seek_read = k12text_seek_read;
317 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
323 static const struct { int e; const char* s; } encaps[] = {
324 { WTAP_ENCAP_ETHERNET, "ETHER" },
325 { WTAP_ENCAP_MTP2, "MTP-L2" },
326 { WTAP_ENCAP_ATM_PDUS, "SSCOP" },
327 { WTAP_ENCAP_MTP3, "SSCF" },
328 { WTAP_ENCAP_CHDLC, "HDLC" },
330 { WTAP_ENCAP_UNKNOWN, "UNKNOWN" },
334 static gboolean k12text_dump(wtap_dumper *wdh _U_, const struct wtap_pkthdr *phdr,
335 const union wtap_pseudo_header *pseudo_header _U_,
336 const guchar *pd, int *err) {
338 size_t left = 196808;
341 const char* str_enc = "";
346 ms = phdr->ts.nsecs / 1000000;
347 ns = (phdr->ts.nsecs - (1000000*ms))/1000;
349 for(i=0; encaps[i].s; i++) {
350 str_enc = encaps[i].s;
351 if (phdr->pkt_encap == encaps[i].e) break;
354 strftime(p,90,"+---------+---------------+----------+\r\n%H:%M:%S,",gmtime(&phdr->ts.secs));
359 wl = g_snprintf(p,left,"%.3d,%.3d %s\r\n|0 |",ms,ns,str_enc);
363 for(i=0;i < phdr->caplen && left > 2; i++) {
364 wl = g_snprintf(p,left,"%.2x|",pd[i]);
369 wl = g_snprintf(p,left,"\r\n\r\n");
373 return wtap_dump_file_write(wdh, buf, strlen(buf), err);
377 gboolean k12text_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err) {
380 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
384 wdh->subtype_write = k12text_dump;
389 int k12text_dump_can_write_encap(int encap) {
391 case WTAP_ENCAP_PER_PACKET:
392 case WTAP_ENCAP_ETHERNET:
393 case WTAP_ENCAP_MTP3:
394 case WTAP_ENCAP_CHDLC:
395 case WTAP_ENCAP_UNKNOWN:
397 case WTAP_ENCAP_MTP2:
398 case WTAP_ENCAP_ATM_PDUS:
400 return WTAP_ERR_UNSUPPORTED_ENCAP;
405 * We want to stop processing when we get to the end of the input.
406 * (%option noyywrap is not used because if used then
407 * some flex versions (eg: 2.5.35) generate code which causes
408 * warnings by the Windows VC compiler).