aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap/eri_enb_log.c
blob: 8ab5269107c292c0f9f453fd8b2973b25358f54c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* eri_enb_log.c
 *
 * Ericsson eNode-B raw log file format decoder for the Wiretap library.
 *
 * Wiretap Library
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "eri_enb_log.h"

#include <string.h>

#include "file_wrappers.h"
#include "wtap-int.h"

static const char eri_enb_log_magic[] = "com_ericsson";

static int eri_enb_log_file_type_subtype = -1;

void register_eri_enb_log(void);

#define MAX_LINE_LENGTH            131072

static gboolean eri_enb_log_get_packet(FILE_T fh, wtap_rec* rec,
	Buffer* buf, int* err _U_, gchar** err_info _U_)
{
	static char line[MAX_LINE_LENGTH];
	/* Read in a line */
	gint64 pos_before = file_tell(fh);

	while (file_gets(line, sizeof(line), fh) != NULL)
	{
		nstime_t packet_time;
		gint length;
		/* Set length (avoiding strlen()) and offset.. */
		length = (gint)(file_tell(fh) - pos_before);

		/* ...but don't want to include newline in line length */
		if (length > 0 && line[length - 1] == '\n') {
			line[length - 1] = '\0';
			length = length - 1;
		}
		/* Nor do we want '\r' (as will be written when log is created on windows) */
		if (length > 0 && line[length - 1] == '\r') {
			line[length - 1] = '\0';
			length = length - 1;
		}

		if (0 < iso8601_to_nstime(&packet_time, line+1, ISO8601_DATETIME)) {
			rec->ts.secs = packet_time.secs;
			rec->ts.nsecs = packet_time.nsecs;
			rec->presence_flags |= WTAP_HAS_TS;
		} else {
			rec->ts.secs = 0;
			rec->ts.nsecs = 0;
			rec->presence_flags = 0; /* no time stamp, no separate "on the wire" length */
		}
		/* We've got a full packet! */
		rec->rec_type = REC_TYPE_PACKET;
		rec->block = wtap_block_create(WTAP_BLOCK_PACKET);
		rec->rec_header.packet_header.caplen = length;
		rec->rec_header.packet_header.len = length;

		*err = 0;

		/* Make sure we have enough room for the packet */
		ws_buffer_assure_space(buf, rec->rec_header.packet_header.caplen);
		memcpy(ws_buffer_start_ptr(buf), line, rec->rec_header.packet_header.caplen);

		return TRUE;

	}
	return FALSE;
}

/* Find the next packet and parse it; called from wtap_read(). */
static gboolean eri_enb_log_read(wtap* wth, wtap_rec* rec, Buffer* buf,
	int* err, gchar** err_info, gint64* data_offset)
{
	*data_offset = file_tell(wth->fh);

	return eri_enb_log_get_packet(wth->fh, rec, buf, err, err_info);
}

/* Used to read packets in random-access fashion */
static gboolean eri_enb_log_seek_read(wtap* wth, gint64 seek_off,
	wtap_rec* rec, Buffer* buf, int* err, gchar** err_info)
{
	if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
	{
		return FALSE;
	}

	return eri_enb_log_get_packet(wth->random_fh, rec, buf, err, err_info);
}

wtap_open_return_val
eri_enb_log_open(wtap *wth, int *err, gchar **err_info)
{
	char line1[64];

	/* Look for Gammu DCT3 trace header */
	if (file_gets(line1, sizeof(line1), wth->fh) == NULL)
	{
		*err = file_error(wth->fh, err_info);
		if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	if (g_strstr_len(line1, sizeof(line1), eri_enb_log_magic) == NULL)
	{
		return WTAP_OPEN_NOT_MINE;
	}

	if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
		return WTAP_OPEN_ERROR;

	wth->file_type_subtype = eri_enb_log_file_type_subtype;
	wth->file_encap = WTAP_ENCAP_ERI_ENB_LOG;
	wth->file_tsprec = WTAP_TSPREC_NSEC;
	wth->subtype_read = eri_enb_log_read;
	wth->subtype_seek_read = eri_enb_log_seek_read;
	wth->snapshot_length = 0;

	return WTAP_OPEN_MINE;
}

static const struct supported_block_type eri_enb_log_blocks_supported[] = {
	/*
	 * This is a file format that we dissect, so we provide
	 * only one "packet" with the file's contents, and don't
	 * support any options.
	 */
	{ WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED }
};

static const struct file_type_subtype_info eri_enb_log_info = {
	"Ericsson eNode-B raw log", "eri_enb_log", "eri_enb_log", NULL,
	FALSE, BLOCKS_SUPPORTED(eri_enb_log_blocks_supported),
	NULL, NULL, NULL
};

void register_eri_enb_log(void)
{
	eri_enb_log_file_type_subtype = wtap_register_file_type_subtype(&eri_enb_log_info);

	/*
	 * Register name for backwards compatibility with the
	 * wtap_filetypes table in Lua.
	 */
	//wtap_register_backwards_compatibility_lua_name("MP4",
	//    eri_enb_log_file_type_subtype);
}

/*
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
 *
 * Local variables:
 * c-basic-offset: 8
 * tab-width: 8
 * indent-tabs-mode: t
 * End:
 *
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
 * :indentSize=8:tabSize=8:noTabs=false:
 */