Revert "LATER... ei_kerberos_kdc_session_key ..."
[wireshark-sm.git] / wiretap / stanag4607.c
blob40a370f8b74d0abc80a9ce549b90d6f1fa460e4e
1 /* stanag4607.c
3 * STANAG 4607 file reading
5 * http://www.nato.int/structur/AC/224/standard/4607/4607e_JAS_ED3.pdf
6 * That is now missing from that site, but is available on the Wayback
7 * Machine:
9 * https://web.archive.org/web/20130223054955/http://www.nato.int/structur/AC/224/standard/4607/4607.htm
11 * https://nso.nato.int/nso/zPublic/ap/aedp-7(2).pdf
13 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "config.h"
17 #include "stanag4607.h"
19 #include "wtap-int.h"
20 #include "file_wrappers.h"
21 #include <wsutil/buffer.h>
23 typedef struct {
24 time_t base_secs;
25 } stanag4607_t;
27 #define PKT_HDR_SIZE 32 /* size of a packet header */
28 #define SEG_HDR_SIZE 5 /* size of a segment header */
30 static int stanag4607_file_type_subtype = -1;
32 void register_stanag4607(void);
34 static bool is_valid_id(uint16_t version_id)
36 #define VERSION_21 0x3231
37 #define VERSION_30 0x3330
38 if ((version_id != VERSION_21) &&
39 (version_id != VERSION_30))
40 /* Not a stanag4607 file */
41 return false;
42 return true;
45 static bool stanag4607_read_file(wtap *wth, FILE_T fh, wtap_rec *rec,
46 Buffer *buf, int *err, char **err_info)
48 stanag4607_t *stanag4607 = (stanag4607_t *)wth->priv;
49 uint32_t millisecs, secs, nsecs;
50 int64_t offset = 0;
51 uint8_t stanag_pkt_hdr[PKT_HDR_SIZE+SEG_HDR_SIZE];
52 uint32_t packet_size;
54 *err = 0;
56 /* Combined packet header and segment header */
57 if (!wtap_read_bytes_or_eof(fh, stanag_pkt_hdr, sizeof stanag_pkt_hdr, err, err_info))
58 return false;
59 offset += sizeof stanag_pkt_hdr;
61 if (!is_valid_id(pntoh16(&stanag_pkt_hdr[0]))) {
62 *err = WTAP_ERR_BAD_FILE;
63 *err_info = g_strdup("Bad version number");
64 return false;
67 rec->rec_type = REC_TYPE_PACKET;
68 rec->block = wtap_block_create(WTAP_BLOCK_PACKET);
70 /* The next 4 bytes are the packet length */
71 packet_size = pntoh32(&stanag_pkt_hdr[2]);
72 if (packet_size > WTAP_MAX_PACKET_SIZE_STANDARD) {
74 * Probably a corrupt capture file; don't blow up trying
75 * to allocate space for an immensely-large packet.
77 *err = WTAP_ERR_BAD_FILE;
78 *err_info = ws_strdup_printf("stanag4607: File has %" PRIu32 "d-byte packet, "
79 "bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE_STANDARD);
80 return false;
82 if (packet_size < PKT_HDR_SIZE+SEG_HDR_SIZE) {
84 * Probably a corrupt capture file; don't, for example, loop
85 * infinitely if the size is zero.
87 *err = WTAP_ERR_BAD_FILE;
88 *err_info = ws_strdup_printf("stanag4607: File has %" PRIu32 "d-byte packet, "
89 "smaller than minimum of %u", packet_size, PKT_HDR_SIZE+SEG_HDR_SIZE);
90 return false;
92 rec->rec_header.packet_header.caplen = packet_size;
93 rec->rec_header.packet_header.len = packet_size;
95 /* Sadly, the header doesn't contain times; but some segments do */
96 /* So, get the segment header, which is just past the 32-byte header. */
97 rec->presence_flags = WTAP_HAS_TS;
99 /* If no time specified, it's the last baseline time */
100 rec->ts.secs = stanag4607->base_secs;
101 rec->ts.nsecs = 0;
102 millisecs = 0;
104 #define MISSION_SEGMENT 1
105 #define DWELL_SEGMENT 2
106 #define JOB_DEFINITION_SEGMENT 5
107 #define PLATFORM_LOCATION_SEGMENT 13
108 if (MISSION_SEGMENT == stanag_pkt_hdr[32]) {
109 uint8_t mseg[39];
110 struct tm tm;
112 if (!wtap_read_bytes(fh, &mseg, sizeof mseg, err, err_info))
113 return false;
114 offset += sizeof mseg;
116 tm.tm_year = pntoh16(&mseg[35]) - 1900;
117 tm.tm_mon = mseg[37] - 1;
118 tm.tm_mday = mseg[38];
119 tm.tm_hour = 0;
120 tm.tm_min = 0;
121 tm.tm_sec = 0;
122 tm.tm_isdst = -1;
123 stanag4607->base_secs = mktime(&tm);
124 rec->ts.secs = stanag4607->base_secs;
126 else if (PLATFORM_LOCATION_SEGMENT == stanag_pkt_hdr[32]) {
127 if (!wtap_read_bytes(fh, &millisecs, sizeof millisecs, err, err_info))
128 return false;
129 offset += sizeof millisecs;
130 millisecs = g_ntohl(millisecs);
132 else if (DWELL_SEGMENT == stanag_pkt_hdr[32]) {
133 uint8_t dseg[19];
134 if (!wtap_read_bytes(fh, &dseg, sizeof dseg, err, err_info))
135 return false;
136 offset += sizeof dseg;
137 millisecs = pntoh32(&dseg[15]);
139 if (0 != millisecs) {
140 secs = millisecs/1000;
141 nsecs = (millisecs - 1000 * secs) * 1000000;
142 rec->ts.secs = stanag4607->base_secs + secs;
143 rec->ts.nsecs = nsecs;
146 /* wind back to the start of the packet ... */
147 if (file_seek(fh, - offset, SEEK_CUR, err) == -1)
148 return false;
150 return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
153 static bool stanag4607_read(wtap *wth, wtap_rec *rec, Buffer *buf,
154 int *err, char **err_info, int64_t *data_offset)
156 *data_offset = file_tell(wth->fh);
158 return stanag4607_read_file(wth, wth->fh, rec, buf, err, err_info);
161 static bool stanag4607_seek_read(wtap *wth, int64_t seek_off,
162 wtap_rec *rec,
163 Buffer *buf, int *err, char **err_info)
165 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
166 return false;
168 return stanag4607_read_file(wth, wth->random_fh, rec, buf, err, err_info);
171 wtap_open_return_val stanag4607_open(wtap *wth, int *err, char **err_info)
173 uint16_t version_id;
174 stanag4607_t *stanag4607;
176 if (!wtap_read_bytes(wth->fh, &version_id, sizeof version_id, err, err_info))
177 return (*err != WTAP_ERR_SHORT_READ) ? WTAP_OPEN_ERROR : WTAP_OPEN_NOT_MINE;
179 if (!is_valid_id(GUINT16_TO_BE(version_id)))
180 /* Not a stanag4607 file */
181 return WTAP_OPEN_NOT_MINE;
183 /* seek back to the start of the file */
184 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
185 return WTAP_OPEN_ERROR;
187 wth->file_type_subtype = stanag4607_file_type_subtype;
188 wth->file_encap = WTAP_ENCAP_STANAG_4607;
189 wth->snapshot_length = 0; /* not known */
191 stanag4607 = g_new(stanag4607_t, 1);
192 wth->priv = (void *)stanag4607;
193 stanag4607->base_secs = 0; /* unknown as of yet */
195 wth->subtype_read = stanag4607_read;
196 wth->subtype_seek_read = stanag4607_seek_read;
197 wth->file_tsprec = WTAP_TSPREC_MSEC;
200 * Add an IDB; we don't know how many interfaces were
201 * involved, so we just say one interface, about which
202 * we only know the link-layer type, snapshot length,
203 * and time stamp resolution.
205 wtap_add_generated_idb(wth);
207 return WTAP_OPEN_MINE;
210 static const struct supported_block_type stanag4607_blocks_supported[] = {
212 * We support packet blocks, with no comments or other options.
214 { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED }
217 static const struct file_type_subtype_info stanag4607_info = {
218 "STANAG 4607 Format", "stanag4607", NULL, NULL,
219 false, BLOCKS_SUPPORTED(stanag4607_blocks_supported),
220 NULL, NULL, NULL
223 void register_stanag4607(void)
225 stanag4607_file_type_subtype = wtap_register_file_type_subtype(&stanag4607_info);
228 * Register name for backwards compatibility with the
229 * wtap_filetypes table in Lua.
231 wtap_register_backwards_compatibility_lua_name("STANAG_4607",
232 stanag4607_file_type_subtype);
236 * Editor modelines - https://www.wireshark.org/tools/modelines.html
238 * Local Variables:
239 * c-basic-offset: 2
240 * tab-width: 8
241 * indent-tabs-mode: nil
242 * End:
244 * vi: set shiftwidth=2 tabstop=8 expandtab:
245 * :indentSize=2:tabSize=8:noTabs=true: