/src/wireshark/wiretap/eyesdn.c
Line | Count | Source |
1 | | /* eyesdn.c |
2 | | * |
3 | | * Wiretap Library |
4 | | * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> |
5 | | * |
6 | | * SPDX-License-Identifier: GPL-2.0-or-later |
7 | | */ |
8 | | |
9 | | #include "config.h" |
10 | | #include "eyesdn.h" |
11 | | #include "wtap_module.h" |
12 | | #include "file_wrappers.h" |
13 | | |
14 | | #include <stdlib.h> |
15 | | #include <string.h> |
16 | | |
17 | | #include <wsutil/pint.h> |
18 | | |
19 | | static int eyesdn_file_type_subtype = -1; |
20 | | |
21 | | void register_eyesdn(void); |
22 | | |
23 | | /* This module reads the output of the EyeSDN USB S0/E1 ISDN probes |
24 | | * They store HDLC frames of D and B channels in a binary format |
25 | | * The fileformat is |
26 | | * |
27 | | * 1-6 Byte: EyeSDN - Magic |
28 | | * 7-n Byte: Frames |
29 | | * |
30 | | * Each Frame starts with the 0xff Flag byte |
31 | | * - Bytes 0-2: timestamp (usec in network byte order) |
32 | | * - Bytes 3-7: timestamp (40bits sec since 1970 in network byte order) |
33 | | * - Byte 8: channel (0 for D channel, 1-30 for B1-B30) |
34 | | * - Byte 9: Sender Bit 0(0 NT, 1 TE), Protocol in Bits 7:1, see enum |
35 | | * - Byte 10-11: frame size in bytes |
36 | | * - Byte 12-n: Frame Payload |
37 | | * |
38 | | * All multibyte values are represented in network byte order |
39 | | * The frame is terminated with a flag character (0xff) |
40 | | * bytes 0xff within a frame are escaped using the 0xfe escape character |
41 | | * the byte following the escape character is decremented by two: |
42 | | * so 0xfe 0xfd is actually a 0xff |
43 | | * Characters that need to be escaped are 0xff and 0xfe |
44 | | */ |
45 | | |
46 | | |
47 | | static bool esc_read(FILE_T fh, uint8_t *buf, int len, int *err, char **err_info) |
48 | 0 | { |
49 | 0 | int i; |
50 | 0 | int value; |
51 | |
|
52 | 0 | for(i=0; i<len; i++) { |
53 | 0 | value=file_getc(fh); |
54 | 0 | if(value==-1) { |
55 | | /* EOF or error */ |
56 | 0 | *err=file_error(fh, err_info); |
57 | 0 | if(*err==0) |
58 | 0 | *err=WTAP_ERR_SHORT_READ; |
59 | 0 | return false; |
60 | 0 | } |
61 | 0 | if(value==0xff) { |
62 | | /* error !!, read into next frame */ |
63 | 0 | *err=WTAP_ERR_BAD_FILE; |
64 | 0 | *err_info=g_strdup("eyesdn: No flag character seen in frame"); |
65 | 0 | return false; |
66 | 0 | } |
67 | 0 | if(value==0xfe) { |
68 | | /* we need to escape */ |
69 | 0 | value=file_getc(fh); |
70 | 0 | if(value==-1) { |
71 | | /* EOF or error */ |
72 | 0 | *err=file_error(fh, err_info); |
73 | 0 | if(*err==0) |
74 | 0 | *err=WTAP_ERR_SHORT_READ; |
75 | 0 | return false; |
76 | 0 | } |
77 | 0 | value+=2; |
78 | 0 | } |
79 | 0 | buf[i]=value; |
80 | 0 | } |
81 | | |
82 | 0 | return true; |
83 | 0 | } |
84 | | |
85 | | /* Magic text to check for eyesdn-ness of file */ |
86 | | static const unsigned char eyesdn_hdr_magic[] = |
87 | | { 'E', 'y', 'e', 'S', 'D', 'N'}; |
88 | 0 | #define EYESDN_HDR_MAGIC_SIZE sizeof(eyesdn_hdr_magic) |
89 | | |
90 | | /* Size of a record header */ |
91 | 0 | #define EYESDN_HDR_LENGTH 12 |
92 | | |
93 | | static bool eyesdn_read(wtap *wth, wtap_rec *rec, |
94 | | int *err, char **err_info, int64_t *data_offset); |
95 | | static bool eyesdn_seek_read(wtap *wth, int64_t seek_off, |
96 | | wtap_rec *rec, int *err, char **err_info); |
97 | | static bool read_eyesdn_rec(FILE_T fh, wtap_rec *rec, |
98 | | int *err, char **err_info); |
99 | | |
100 | | /* Seeks to the beginning of the next packet, and returns the |
101 | | byte offset. Returns -1 on failure, and sets "*err" to the error |
102 | | and "*err_info" to null or an additional error string. */ |
103 | | static int64_t eyesdn_seek_next_packet(wtap *wth, int *err, char **err_info) |
104 | 0 | { |
105 | 0 | int byte; |
106 | 0 | int64_t cur_off; |
107 | |
|
108 | 0 | while ((byte = file_getc(wth->fh)) != EOF) { |
109 | 0 | if (byte == 0xff) { |
110 | 0 | cur_off = file_tell(wth->fh); |
111 | 0 | if (cur_off == -1) { |
112 | | /* Error. */ |
113 | 0 | *err = file_error(wth->fh, err_info); |
114 | 0 | return -1; |
115 | 0 | } |
116 | 0 | return cur_off; |
117 | 0 | } |
118 | 0 | } |
119 | | /* EOF or error. */ |
120 | 0 | *err = file_error(wth->fh, err_info); |
121 | 0 | return -1; |
122 | 0 | } |
123 | | |
124 | | wtap_open_return_val eyesdn_open(wtap *wth, int *err, char **err_info) |
125 | 0 | { |
126 | 0 | char magic[EYESDN_HDR_MAGIC_SIZE]; |
127 | | |
128 | | /* Look for eyesdn header */ |
129 | 0 | if (!wtap_read_bytes(wth->fh, &magic, sizeof magic, err, err_info)) { |
130 | 0 | if (*err != WTAP_ERR_SHORT_READ) |
131 | 0 | return WTAP_OPEN_ERROR; |
132 | 0 | return WTAP_OPEN_NOT_MINE; |
133 | 0 | } |
134 | 0 | if (memcmp(magic, eyesdn_hdr_magic, EYESDN_HDR_MAGIC_SIZE) != 0) |
135 | 0 | return WTAP_OPEN_NOT_MINE; |
136 | | |
137 | 0 | wth->file_encap = WTAP_ENCAP_PER_PACKET; |
138 | 0 | wth->file_type_subtype = eyesdn_file_type_subtype; |
139 | 0 | wth->snapshot_length = 0; /* not known */ |
140 | 0 | wth->subtype_read = eyesdn_read; |
141 | 0 | wth->subtype_seek_read = eyesdn_seek_read; |
142 | 0 | wth->file_tsprec = WTAP_TSPREC_USEC; |
143 | |
|
144 | 0 | return WTAP_OPEN_MINE; |
145 | 0 | } |
146 | | |
147 | | /* Find the next record and parse it; called from wtap_read(). */ |
148 | | static bool eyesdn_read(wtap *wth, wtap_rec *rec, |
149 | | int *err, char **err_info, int64_t *data_offset) |
150 | 0 | { |
151 | 0 | int64_t offset; |
152 | | |
153 | | /* Find the next record */ |
154 | 0 | offset = eyesdn_seek_next_packet(wth, err, err_info); |
155 | 0 | if (offset < 1) |
156 | 0 | return false; |
157 | 0 | *data_offset = offset; |
158 | | |
159 | | /* Parse the record */ |
160 | 0 | return read_eyesdn_rec(wth->fh, rec, err, err_info); |
161 | 0 | } |
162 | | |
163 | | /* Used to read packets in random-access fashion */ |
164 | | static bool |
165 | | eyesdn_seek_read(wtap *wth, int64_t seek_off, wtap_rec *rec, |
166 | | int *err, char **err_info) |
167 | 0 | { |
168 | 0 | if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) |
169 | 0 | return false; |
170 | | |
171 | 0 | return read_eyesdn_rec(wth->random_fh, rec, err, err_info); |
172 | 0 | } |
173 | | |
174 | | /* Parses a record. */ |
175 | | static bool |
176 | | read_eyesdn_rec(FILE_T fh, wtap_rec *rec, int *err, char **err_info) |
177 | 0 | { |
178 | 0 | union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header; |
179 | 0 | uint8_t hdr[EYESDN_HDR_LENGTH]; |
180 | 0 | time_t secs; |
181 | 0 | int usecs; |
182 | 0 | unsigned pkt_len; |
183 | 0 | uint8_t channel, direction; |
184 | 0 | uint8_t *pd; |
185 | | |
186 | | /* Our file pointer should be at the summary information header |
187 | | * for a packet. Read in that header and extract the useful |
188 | | * information. |
189 | | */ |
190 | 0 | if (!esc_read(fh, hdr, EYESDN_HDR_LENGTH, err, err_info)) |
191 | 0 | return false; |
192 | | |
193 | 0 | wtap_setup_packet_rec(rec, WTAP_ENCAP_UNKNOWN); |
194 | 0 | rec->block = wtap_block_create(WTAP_BLOCK_PACKET); |
195 | | |
196 | | /* extract information from header */ |
197 | 0 | usecs = pntohu24(&hdr[0]); |
198 | 0 | secs = pntohu40(&hdr[3]); |
199 | |
|
200 | 0 | channel = hdr[8]; |
201 | 0 | direction = hdr[9]; |
202 | 0 | pkt_len = pntohu16(&hdr[10]); |
203 | |
|
204 | 0 | switch(direction >> 1) { |
205 | | |
206 | 0 | default: |
207 | 0 | case EYESDN_ENCAP_ISDN: /* ISDN */ |
208 | 0 | pseudo_header->isdn.uton = direction & 1; |
209 | 0 | pseudo_header->isdn.channel = channel; |
210 | 0 | if(channel) { /* bearer channels */ |
211 | 0 | rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_ISDN; /* recognises PPP */ |
212 | 0 | pseudo_header->isdn.uton=!pseudo_header->isdn.uton; /* bug */ |
213 | 0 | } else { /* D channel */ |
214 | 0 | rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_ISDN; |
215 | 0 | } |
216 | 0 | break; |
217 | | |
218 | 0 | case EYESDN_ENCAP_MSG: /* Layer 1 message */ |
219 | 0 | rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_LAYER1_EVENT; |
220 | 0 | pseudo_header->l1event.uton = (direction & 1); |
221 | 0 | break; |
222 | | |
223 | 0 | case EYESDN_ENCAP_LAPB: /* X.25 via LAPB */ |
224 | 0 | rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_LAPB; |
225 | 0 | pseudo_header->dte_dce.flags = (direction & 1) ? 0 : 0x80; |
226 | 0 | break; |
227 | | |
228 | 0 | case EYESDN_ENCAP_ATM: { /* ATM cells */ |
229 | 0 | #define CELL_LEN 53 |
230 | 0 | unsigned char cell[CELL_LEN]; |
231 | 0 | int64_t cur_off; |
232 | |
|
233 | 0 | if(pkt_len != CELL_LEN) { |
234 | 0 | *err = WTAP_ERR_BAD_FILE; |
235 | 0 | *err_info = ws_strdup_printf( |
236 | 0 | "eyesdn: ATM cell has a length != 53 (%u)", |
237 | 0 | pkt_len); |
238 | 0 | return false; |
239 | 0 | } |
240 | | |
241 | 0 | cur_off = file_tell(fh); |
242 | 0 | if (!esc_read(fh, cell, CELL_LEN, err, err_info)) |
243 | 0 | return false; |
244 | 0 | if (file_seek(fh, cur_off, SEEK_SET, err) == -1) |
245 | 0 | return false; |
246 | 0 | rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_ATM_PDUS_UNTRUNCATED; |
247 | 0 | pseudo_header->atm.flags=ATM_RAW_CELL; |
248 | 0 | pseudo_header->atm.aal=AAL_UNKNOWN; |
249 | 0 | pseudo_header->atm.type=TRAF_UMTS_FP; |
250 | 0 | pseudo_header->atm.subtype=TRAF_ST_UNKNOWN; |
251 | 0 | pseudo_header->atm.vpi=((cell[0]&0xf)<<4) + (cell[0]&0xf); |
252 | 0 | pseudo_header->atm.vci=((cell[0]&0xf)<<4) + cell[0]; /* from cell */ |
253 | 0 | pseudo_header->atm.channel=direction & 1; |
254 | 0 | } |
255 | 0 | break; |
256 | | |
257 | 0 | case EYESDN_ENCAP_MTP2: /* SS7 frames */ |
258 | 0 | pseudo_header->mtp2.sent = direction & 1; |
259 | 0 | pseudo_header->mtp2.annex_a_used = MTP2_ANNEX_A_USED_UNKNOWN; |
260 | 0 | pseudo_header->mtp2.link_number = channel; |
261 | 0 | rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_MTP2_WITH_PHDR; |
262 | 0 | break; |
263 | | |
264 | 0 | case EYESDN_ENCAP_DPNSS: /* DPNSS */ |
265 | 0 | pseudo_header->isdn.uton = direction & 1; |
266 | 0 | pseudo_header->isdn.channel = channel; |
267 | 0 | rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_DPNSS; |
268 | 0 | break; |
269 | | |
270 | 0 | case EYESDN_ENCAP_DASS2: /* DASS2 frames */ |
271 | 0 | pseudo_header->isdn.uton = direction & 1; |
272 | 0 | pseudo_header->isdn.channel = channel; |
273 | 0 | rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_DPNSS; |
274 | 0 | break; |
275 | | |
276 | 0 | case EYESDN_ENCAP_BACNET: /* BACNET async over HDLC frames */ |
277 | 0 | pseudo_header->isdn.uton = direction & 1; |
278 | 0 | pseudo_header->isdn.channel = channel; |
279 | 0 | rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR; |
280 | 0 | break; |
281 | | |
282 | 0 | case EYESDN_ENCAP_V5_EF: /* V5EF */ |
283 | 0 | pseudo_header->isdn.uton = direction & 1; |
284 | 0 | pseudo_header->isdn.channel = channel; |
285 | 0 | rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_V5_EF; |
286 | 0 | break; |
287 | 0 | } |
288 | | |
289 | 0 | if(pkt_len > WTAP_MAX_PACKET_SIZE_STANDARD) { |
290 | 0 | *err = WTAP_ERR_BAD_FILE; |
291 | 0 | *err_info = ws_strdup_printf("eyesdn: File has %u-byte packet, bigger than maximum of %u", |
292 | 0 | pkt_len, WTAP_MAX_PACKET_SIZE_STANDARD); |
293 | 0 | return false; |
294 | 0 | } |
295 | | |
296 | 0 | rec->presence_flags = WTAP_HAS_TS; |
297 | 0 | rec->ts.secs = secs; |
298 | 0 | rec->ts.nsecs = usecs * 1000; |
299 | 0 | rec->rec_header.packet_header.caplen = pkt_len; |
300 | 0 | rec->rec_header.packet_header.len = pkt_len; |
301 | | |
302 | | /* Make sure we have enough room for the packet */ |
303 | 0 | ws_buffer_assure_space(&rec->data, pkt_len); |
304 | |
|
305 | 0 | pd = ws_buffer_start_ptr(&rec->data); |
306 | 0 | if (!esc_read(fh, pd, pkt_len, err, err_info)) |
307 | 0 | return false; |
308 | 0 | return true; |
309 | 0 | } |
310 | | |
311 | | |
312 | | static bool |
313 | | esc_write(wtap_dumper *wdh, const uint8_t *buf, int len, int *err) |
314 | 0 | { |
315 | 0 | int i; |
316 | 0 | uint8_t byte; |
317 | 0 | static const uint8_t esc = 0xfe; |
318 | |
|
319 | 0 | for(i=0; i<len; i++) { |
320 | 0 | byte=buf[i]; |
321 | 0 | if(byte == 0xff || byte == 0xfe) { |
322 | | /* |
323 | | * Escape the frame delimiter and escape byte. |
324 | | */ |
325 | 0 | if (!wtap_dump_file_write(wdh, &esc, sizeof esc, err)) |
326 | 0 | return false; |
327 | 0 | byte-=2; |
328 | 0 | } |
329 | 0 | if (!wtap_dump_file_write(wdh, &byte, sizeof byte, err)) |
330 | 0 | return false; |
331 | 0 | } |
332 | 0 | return true; |
333 | 0 | } |
334 | | |
335 | | static bool eyesdn_dump(wtap_dumper *wdh, const wtap_rec *rec, |
336 | | int *err, char **err_info); |
337 | | |
338 | | static bool eyesdn_dump_open(wtap_dumper *wdh, int *err, char **err_info _U_) |
339 | 0 | { |
340 | 0 | wdh->subtype_write=eyesdn_dump; |
341 | |
|
342 | 0 | if (!wtap_dump_file_write(wdh, eyesdn_hdr_magic, |
343 | 0 | EYESDN_HDR_MAGIC_SIZE, err)) |
344 | 0 | return false; |
345 | 0 | *err=0; |
346 | 0 | return true; |
347 | 0 | } |
348 | | |
349 | | static int eyesdn_dump_can_write_encap(int encap) |
350 | 0 | { |
351 | 0 | switch (encap) { |
352 | 0 | case WTAP_ENCAP_ISDN: |
353 | 0 | case WTAP_ENCAP_LAYER1_EVENT: |
354 | 0 | case WTAP_ENCAP_DPNSS: |
355 | 0 | case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED: |
356 | 0 | case WTAP_ENCAP_LAPB: |
357 | 0 | case WTAP_ENCAP_MTP2_WITH_PHDR: |
358 | 0 | case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR: |
359 | 0 | case WTAP_ENCAP_PER_PACKET: |
360 | 0 | return 0; |
361 | | |
362 | 0 | default: |
363 | 0 | return WTAP_ERR_UNWRITABLE_ENCAP; |
364 | 0 | } |
365 | 0 | } |
366 | | |
367 | | /* Write a record for a packet to a dump file. |
368 | | * Returns true on success, false on failure. */ |
369 | | static bool eyesdn_dump(wtap_dumper *wdh, const wtap_rec *rec, |
370 | | int *err, char **err_info _U_) |
371 | 0 | { |
372 | 0 | static const uint8_t start_flag = 0xff; |
373 | 0 | const union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header; |
374 | 0 | uint8_t buf[EYESDN_HDR_LENGTH]; |
375 | 0 | int usecs; |
376 | 0 | time_t secs; |
377 | 0 | int channel; |
378 | 0 | int origin; |
379 | 0 | int protocol; |
380 | 0 | int size; |
381 | | |
382 | | /* We can only write packet records. */ |
383 | 0 | if (rec->rec_type != REC_TYPE_PACKET) { |
384 | 0 | *err = WTAP_ERR_UNWRITABLE_REC_TYPE; |
385 | 0 | *err_info = wtap_unwritable_rec_type_err_string(rec); |
386 | 0 | return false; |
387 | 0 | } |
388 | | |
389 | | /* Don't write out anything bigger than we can read. |
390 | | * (The length field in packet headers is 16 bits, which |
391 | | * imposes a hard limit.) */ |
392 | 0 | if (rec->rec_header.packet_header.caplen > 65535) { |
393 | 0 | *err = WTAP_ERR_PACKET_TOO_LARGE; |
394 | 0 | return false; |
395 | 0 | } |
396 | | |
397 | 0 | usecs=rec->ts.nsecs/1000; |
398 | 0 | secs=rec->ts.secs; |
399 | 0 | size=rec->rec_header.packet_header.caplen; |
400 | 0 | origin = pseudo_header->isdn.uton; |
401 | 0 | channel = pseudo_header->isdn.channel; |
402 | |
|
403 | 0 | switch(rec->rec_header.packet_header.pkt_encap) { |
404 | | |
405 | 0 | case WTAP_ENCAP_ISDN: |
406 | 0 | protocol=EYESDN_ENCAP_ISDN; /* set depending on decoder format and mode */ |
407 | 0 | break; |
408 | | |
409 | 0 | case WTAP_ENCAP_LAYER1_EVENT: |
410 | 0 | protocol=EYESDN_ENCAP_MSG; |
411 | 0 | break; |
412 | | |
413 | 0 | case WTAP_ENCAP_DPNSS: |
414 | 0 | protocol=EYESDN_ENCAP_DPNSS; |
415 | 0 | break; |
416 | | |
417 | | #if 0 |
418 | | case WTAP_ENCAP_DASS2: |
419 | | protocol=EYESDN_ENCAP_DASS2; |
420 | | break; |
421 | | #endif |
422 | | |
423 | 0 | case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED: |
424 | 0 | protocol=EYESDN_ENCAP_ATM; |
425 | 0 | channel=0x80; |
426 | 0 | break; |
427 | | |
428 | 0 | case WTAP_ENCAP_LAPB: |
429 | 0 | protocol=EYESDN_ENCAP_LAPB; |
430 | 0 | break; |
431 | | |
432 | 0 | case WTAP_ENCAP_MTP2_WITH_PHDR: |
433 | 0 | protocol=EYESDN_ENCAP_MTP2; |
434 | 0 | break; |
435 | | |
436 | 0 | case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR: |
437 | 0 | protocol=EYESDN_ENCAP_BACNET; |
438 | 0 | break; |
439 | | |
440 | 0 | case WTAP_ENCAP_V5_EF: |
441 | 0 | protocol=EYESDN_ENCAP_V5_EF; |
442 | 0 | break; |
443 | | |
444 | 0 | default: |
445 | 0 | *err=WTAP_ERR_UNWRITABLE_ENCAP; |
446 | 0 | return false; |
447 | 0 | } |
448 | | |
449 | 0 | phtonu24(&buf[0], usecs); /* 0-2 */ |
450 | 0 | phtonu40(&buf[3], secs); /* 3-7 */ |
451 | 0 | phtonu8(&buf[8], channel); /* 8 */ |
452 | 0 | phtonu8(&buf[9], (origin?1:0) + (protocol << 1)); /* 9 */ |
453 | 0 | phtonu16(&buf[10], size); /* 10-11 */ |
454 | | |
455 | | /* start flag */ |
456 | 0 | if (!wtap_dump_file_write(wdh, &start_flag, sizeof start_flag, err)) |
457 | 0 | return false; |
458 | 0 | if (!esc_write(wdh, buf, 12, err)) |
459 | 0 | return false; |
460 | 0 | if (!esc_write(wdh, ws_buffer_start_ptr(&rec->data), size, err)) |
461 | 0 | return false; |
462 | 0 | return true; |
463 | 0 | } |
464 | | |
465 | | static const struct supported_block_type eyesdn_blocks_supported[] = { |
466 | | /* |
467 | | * We support packet blocks, with no comments or other options. |
468 | | */ |
469 | | { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED } |
470 | | }; |
471 | | |
472 | | static const struct file_type_subtype_info eyesdn_info = { |
473 | | "EyeSDN USB S0/E1 ISDN trace format", "eyesdn", "trc", NULL, |
474 | | false, BLOCKS_SUPPORTED(eyesdn_blocks_supported), |
475 | | eyesdn_dump_can_write_encap, eyesdn_dump_open, NULL |
476 | | }; |
477 | | |
478 | | void register_eyesdn(void) |
479 | 14 | { |
480 | 14 | eyesdn_file_type_subtype = wtap_register_file_type_subtype(&eyesdn_info); |
481 | | |
482 | | /* |
483 | | * Register name for backwards compatibility with the |
484 | | * wtap_filetypes table in Lua. |
485 | | */ |
486 | 14 | wtap_register_backwards_compatibility_lua_name("EYESDN", |
487 | 14 | eyesdn_file_type_subtype); |
488 | 14 | } |
489 | | |
490 | | /* |
491 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
492 | | * |
493 | | * Local variables: |
494 | | * c-basic-offset: 8 |
495 | | * tab-width: 8 |
496 | | * indent-tabs-mode: t |
497 | | * End: |
498 | | * |
499 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
500 | | * :indentSize=8:tabSize=8:noTabs=false: |
501 | | */ |