Newer
Older
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
/* Header for jnetpcap_utils utility methods */
#ifndef _Included_jnetpcap_packet_jscanner_h
#define _Included_jnetpcap_packet_jscanner_h
#ifdef __cplusplus
#include <stdint.h>
#include "export.h"
#include "org_jnetpcap_packet_JScanner.h"
#include "org_jnetpcap_packet_JRegistry.h"
#include "org_jnetpcap_packet_JPacket_State.h"
#include "org_jnetpcap_packet_JHeader_State.h"
#include "org_jnetpcap_protocol_JProtocol.h"
#include "packet_flow.h"
#include "util_debug.h"
/******************************
******************************
*/
#define JREGISTRY org_jnetpcap_packet_JRegistry_
#define MAX_ID_COUNT org_jnetpcap_packet_JRegistry_MAX_ID_COUNT
#define FLAG_OVERRIDE_LENGTH org_jnetpcap_packet_JRegistry_FLAG_OVERRIDE_LENGTH
#define FLAG_OVERRIDE_BINDING org_jnetpcap_packet_JRegistry_FLAG_OVERRIDE_BINDING
#define FLAG_HEURISTIC_BINDING org_jnetpcap_packet_JRegistry_FLAG_HEURISTIC_BINDING
#define FLAG_HEURISTIC_PRE_BINDING org_jnetpcap_packet_JRegistry_FLAG_HEURISTIC_PRE_BINDING
#define JSCANNER org_jnetpcap_packet_JScanner_
#define MAX_ENTRY_COUNT org_jnetpcap_packet_JScanner_MAX_ENTRY_COUNT
#define JPROTOCOL org_jnetpcap_protocol_JProtocol_
#define PAYLOAD_ID org_jnetpcap_protocol_JProtocol_PAYLOAD_ID
#define JPACKET org_jnetpcap_packet_JPacket_State_
#define PACKET_FLAG_TRUNCATED org_jnetpcap_packet_JPacket_State_FLAG_TRUNCATED
#define JHEADER org_jnetpcap_packet_JHeader_State_
#define HEADER_FLAG_PREFIX_TRUNCATED org_jnetpcap_packet_JHeader_State_FLAG_PREFIX_TRUNCATED
#define HEADER_FLAG_HEADER_TRUNCATED org_jnetpcap_packet_JHeader_State_FLAG_HEADER_TRUNCATED
#define HEADER_FLAG_PAYLOAD_TRUNCATED org_jnetpcap_packet_JHeader_State_FLAG_PAYLOAD_TRUNCATED
#define HEADER_FLAG_GAP_TRUNCATED org_jnetpcap_packet_JHeader_State_FLAG_GAP_TRUNCATED
#define HEADER_FLAG_POSTFIX_TRUNCATED org_jnetpcap_packet_JHeader_State_FLAG_POSTFIX_TRUNCATED
#define HEADER_FLAG_HEURISTIC_BINDING org_jnetpcap_packet_JHeader_State_FLAG_HEURISTIC_BINDING
#define HEADER_FLAG_CRC_PERFORMED org_jnetpcap_packet_JHeader_State_FLAG_CRC_PERFORMED
#define HEADER_FLAG_CRC_INVALID org_jnetpcap_packet_JHeader_State_FLAG_CRC_INVALID
#define HEADER_FLAG_FRAGMENTED org_jnetpcap_packet_JHeader_State_FLAG_HEADER_FRAGMENTED
#define HEADER_FLAG_SUBHEADERS_DISSECTED org_jnetpcap_packet_JHeader_State_FLAG_SUBHEADERS_DISSECTED
#define HEADER_FLAG_FIELDS_DISSECTED org_jnetpcap_packet_JHeader_State_FLAG_FIELDS_DISSECTED
#define HEADER_FLAG_IGNORE_BOUNDS org_jnetpcap_packet_JHeader_State_FLAG_IGNORE_BOUNDS
#define HEADER_FLAG_HEADER_FRAGMENTED org_jnetpcap_packet_JHeader_State_FLAG_HEADER_FRAGMENTED
/* Cumulative flags. Flags which are passed to subsequent encapsulated headers */
#define CUMULATIVE_FLAG_HEADER_FRAGMENTED \
HEADER_FLAG_HEADER_FRAGMENTED | \
HEADER_FLAG_IGNORE_BOUNDS
#define CUMULATIVE_FLAG_MASK CUMULATIVE_FLAG_HEADER_FRAGMENTED
#define INVALID PAYLOAD_ID
#define ACCESS(offset) if (is_accessible(scan, offset) == FALSE) return;
/******************************
******************************
*/
extern jclass jheaderScannerClass;
extern jmethodID scanHeaderMID;
/******************************
******************************
*/
// Forward references
struct scanner_t;
struct packet_state_t;
struct header_t;
struct scan_t;
struct dissect_t;
/*
* Array of function pointers. These functions perform a per protocol scan
* and return the next header. They also return the length of the header in
* the supplied int pointer.
*/
void init_native_protocols();
typedef void (*native_protocol_func_t)(scan_t *scan);
typedef int (*native_validate_func_t)(scan_t *scan);
typedef void (*native_dissect_func_t)(dissect_t *dissect);
typedef void (*native_debug_func_t)(void *hdr);
extern native_protocol_func_t native_protocols[];
extern native_validate_func_t native_heuristics[MAX_ID_COUNT][MAX_ID_COUNT];
extern native_debug_func_t native_debug[];
extern const char *native_protocol_names[];
void callJavaHeaderScanner(scan_t *scan);
void record_header(scan_t *scan);
void adjustForTruncatedPacket(scan_t *scan);
extern char str_buf[1024];
/**
* Experimental structures to be used in header dissection, that is complete header
* structural breakdown. dissected_t records individual field information within
* the header. Also record information about sub-headers which are within the
* main header. Structure within the header is bitbased not byte based since
* any field within a header might occur at any particular bit offset into the
* header.
*
* Dissectors only record information about non-static fields headers. Static
* fields don't need description since they are always at the same offset and
* length.
*/
//#define DISSECTOR_TYPE_FIELD 1
//#define DISSECTOR_TYPE_HEADER 2
//
#define DISSECTOR_FLAG_FIELDS 0x0001
#define DISSECTOR_FLAG_HEADERS 0x0002
//
//typedef union dfield_t {
// uint8_t dt_id;
// uint16_t dt_flags;
// uint16_t dt_offset; // in bits
// uint16_t dt_length; // in bits
//} dfield_t;
/*
* Structure maintains state for the duration of a header dissection.
*/
typedef struct dissect_t {
JNIEnv *env;
packet_state_t *d_packet;
header_t *d_header;
scanner_t *d_scanner;
uint8_t *d_buf;
int d_buf_len;
int d_offset;
} dissect_t;
/*
* Structure maintains state for the duration of the scan in progress
*
* The structure keeps track of the packet buffer and 3 types of lengths.
* 1) mem_len is the actual total length of the buffer in memory
* 2) wire_len is the length of the original packet when it was captured before
* it was truncated
* 3) buf_len is the runtime/effectual length of the buffer used by the scanner
* methods. This length may shrink if a protocol uses postfix for padding
* or some kind of trailer. The buf_len field is reduced by the scanner
* for that header by the appropriate amount so that next header doesn't
* consider the previous header's postfix as valid part of the packet it
* needs to decode.
*/
typedef struct scan_t {
JNIEnv *env;
jobject jscanner;
jobject jpacket;
jobject jscan; // This structure as a java object
scanner_t *scanner;
packet_state_t *packet;
header_t *header;
char *buf;
int buf_len;
int wire_len;
int mem_len;
int offset;
int length;
int id;
int next_id;
int flags;
int hdr_prefix;
int hdr_gap;
int hdr_payload;
int hdr_postfix;
int hdr_flags;
int is_recorded;
int hdr_count;
int hdr_index;
} scan_t;
#define SCAN_IS_FRAGMENT(scan) (scan->flags & HEADER_FLAG_FRAGMENTED)
#define SCAN_IGNORE_BOUNDS(scan) (scan->flags & HEADER_FLAG_IGNORE_BOUNDS)
#define SCAN_IS_PREFIX_TRUNCATED(scan) (scan->flags & HEADER_FLAG_PREFIX_TRUNCATED)
#define SCAN_IS_HEADER_TRUNCATED(scan) (scan->flags & HEADER_FLAG_HEADER_TRUNCATED)
#define SCAN_IS_GAP_TRUNCATED(scan) (scan->flags & HEADER_FLAG_GAP_TRUNCATED)
#define SCAN_IS_PAYLOAD_TRUNCATED(scan) (scan->flags & HEADER_FLAG_PAYLOAD_TRUNCATED)
#define SCAN_IS_POSTFIX_TRUNCATED(scan) (scan->flags & HEADER_FLAG_POSTFIX_TRUNCATED)
/*
* Each header "record" may have the following physical structure:
* +-------------------------------------------+
* | prefix | header | gap | payload | postfix |
* +-------------------------------------------+
*
* Offset points at the start of the header, not the prefix. In order to calculate
* the exact start of the record, you must subtract the prefix length from the
* offset as follows:
*
* prefix_offset = hdr_offset - hdr_prefix;
*
* To calculate the offset of the start of the payload:
*
* payload_offset = hdr_offset + hdr_length + hdr_gap;
*
* To calculate the offset of the start of the postfix
*
* postfix_offset = hdr_offset + hdr_length + hdr_gap + hdr_payload;
*
* To calculate the end of the header record:
*
* end_offset = hdr_offset + hdr_length + hdr_gap + hdr_payload + hdr_postifx;
*
* Note that most of the time the fields hdr_prefix, hdr_gap and hdr_postfix
* will be zero, but this structure does allow a more complex headers in a
* frame to exist. Some protocols have prefixes such Ethernet2 frames on BSD
* systems and a trailer (represented as a postfix) which may contains padding,
* CRC counters etc. Rtp header for example utilizes padding after its payload
* and so do many other protocols. As of right now, the author is not aware of
* any protocols utilizing an inter header-to-payload gap, which is another way
* of saying a header-padding. None the less, the structure for gap is
* represented here for future compatibility.
*/
typedef struct header_t {
uint8_t hdr_id; // header ID
uint8_t hdr_prefix; // length of the prefix (preamble) before the header
uint8_t hdr_gap; // length of the gap between header and payload
uint16_t hdr_flags; // flags for this header
uint16_t hdr_postfix; // length of the postfix (trailer) after the payload
uint32_t hdr_offset; // offset into the packet_t->data buffer
uint32_t hdr_length; // length of the header in packet_t->data buffer
uint32_t hdr_payload; // length of the payload
uint8_t hdr_subcount; // number of sub-headers
header_t *hdr_subheader; // Index of the first subheader in packet_t
jobject hdr_analysis; // Java JAnalysis based object if not null
} header_t;
typedef struct packet_state_t {
flow_key_t pkt_flow_key; // Flow key calculated for this packet, must be first
uint8_t pkt_flags; // flags for this packet
jobject pkt_analysis; // Java JAnalysis based object if not null
uint64_t pkt_frame_num; // Packet's frame number assigned by scanner
uint64_t pkt_header_map; // bit map of presence of headers
uint32_t pkt_wirelen; // Original packet size
int8_t pkt_header_count; // total number of main headers found
header_t pkt_headers[]; // One per header + 1 more for payload
int8_t pkt_subheader_count; // total number of sub headers found
header_t pkt_subheaders[]; // One per header + 1 more for payload
} packet_state_t;
typedef struct scanner_t {
int32_t sc_len; // bytes allocated for sc_packets buffer
uint64_t sc_cur_frame_num; // Current frame number
uint32_t sc_flags[MAX_ID_COUNT]; // protocol flags
// uint64_t sc_native_header_scanner_map; // java binding map
jobject sc_jscan; // Java JScan structure for interacting with java space
jobject sc_java_header_scanners[MAX_ID_COUNT]; // java scanners
/*
* A per scanner instance table that can be populated with native and
* java scanners at the same time.
*/
native_protocol_func_t sc_scan_table[MAX_ID_COUNT];
native_validate_func_t sc_heuristics_table[MAX_ID_COUNT][MAX_ID_COUNT]; // Huristic
/* Packet and main header ring-buffer */
int sc_offset; // offset into sc_packets for next packet
packet_state_t *sc_packet; // ptr into scanner_t where the first packet begins
/* Sub-header ring buffer */
int sc_sublen; // Length of the sub-header ring-buffer
int sc_subindex; // sub-header offset
header_t *sc_subheader; // ptr where first sub-headers begin
int sc_heap_len;
int sc_heap_offset;
jobject sc_heap_owner;
uint8_t *sc_heap;
} scanner_t;
/******************************
******************************
*/
int scan(JNIEnv *env, jobject obj, jobject jpacket, scanner_t *scanner, packet_state_t *packet,
int first_id, char *buf, int buf_length, uint32_t wirelen);
int scanJPacket(JNIEnv *env, jobject obj, jobject jpacket, jobject jstate, scanner_t *scanner, int first_id, char *buf,
int buf_length, uint32_t wirelen);
int scanJavaBinding(scan_t *scan);
uint64_t toUlong64(JNIEnv *env, jintArray ja);
jint findHeaderById(packet_state_t *packet, jint id, jint instance);
const char *id2str(int id);
int validate(int id, scan_t *);
int validate_next(int id, scan_t *);
/****
* Temporarily backed out of C++ Debug class and G++ compiler
*
extern Debug scanner_logger;
extern Debug protocol_logger;
*****/
/**
* Checks and calculates if there is enough data in the
* buffer to access entire header, if not the header's
* TRUNCATE flag is set and header's length set to wire_len.
*
* scan->length is the input and output with theoretical header length.
* scan->wire_len is the input with actual buffer length.
* scan->hdr_flags output with TRUNCATED flag set.
*/
int truncate_header(scan_t *scan);
int is_accessible(scan_t *scan, int offset);
#endif
#endif