コード例 #1
0
/**
 * ByteBuffer dispatcher that allocates a new java.nio.ByteBuffer and dispatches
 * it to java listener.
 */
void cb_byte_buffer_dispatch(u_char *user, const pcap_pkthdr *pkt_header,
		const u_char *pkt_data) {

	cb_byte_buffer_t *data = (cb_byte_buffer_t *)user;

	JNIEnv *env = data->env;

	setJMemoryPhysical(env, data->header, toLong((void*)pkt_header));

	jobject buffer = env->NewDirectByteBuffer((void *)pkt_data,
			pkt_header->caplen);
	if (buffer == NULL) {
		return;
	}

	env->CallVoidMethod(
			data->obj,
			data->mid,
			(jobject) data->header,
			(jobject) buffer,
			(jobject) data->user);

	env->DeleteLocalRef(buffer);

	if (env->ExceptionCheck() == JNI_TRUE) {
		data->exception = env->ExceptionOccurred();
		pcap_breakloop(data->p);
	}
}
コード例 #2
0
/*
 * Class:     org_jnetpcap_packet_JPacket_State
 * Method:    peerHeaderByIndex
 * Signature: (ILorg/jnetpcap/packet/JHeader$State;)I
 */
JNIEXPORT jint JNICALL Java_org_jnetpcap_packet_JPacket_00024State_peerHeaderByIndex
  (JNIEnv *env, jobject obj, jint index, jobject dst) {
	
	packet_state_t *packet = (packet_state_t *)getJMemoryPhysical(env, obj);
	if (packet == NULL) {
		return -1;
	}
	
	if (index >= packet->pkt_header_count) {
		return -1;
	}
	
	setJMemoryPhysical(env, dst, toLong(&packet->pkt_headers[index]));

	return sizeof(header_t);
}
コード例 #3
0
/*
 * Class:     org_jnetpcap_packet_JPacket_State
 * Method:    peerHeaderById
 * Signature: (IILorg/jnetpcap/packet/JHeader$State;)I
 */
JNIEXPORT jint JNICALL Java_org_jnetpcap_packet_JPacket_00024State_peerHeaderById
  (JNIEnv *env, jobject obj, jint id, jint instance, jobject dst) {
	
	packet_state_t *packet = (packet_state_t *)getJMemoryPhysical(env, obj);
	if (packet == NULL) {
		return -1;
	}
	
	int index = findHeaderById(packet, id, instance);
	if (index == -1) {
		return -1;
	}
	
	setJMemoryPhysical(env, dst, toLong(&packet->pkt_headers[index]));
	jobject keeper = env->GetObjectField(obj, jmemoryKeeperFID);
	env->SetObjectField(dst, jmemoryKeeperFID, keeper);

	return sizeof(header_t);
}
コード例 #4
0
/*
 * Class:     org_jnetpcap_packet_JHeaderScanner
 * Method:    bindNativeScanner
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_org_jnetpcap_packet_JHeaderScanner_bindNativeScanner
(JNIEnv *env, jobject obj, jint id) {

	if (id < 0 || id > MAX_ID_COUNT) {
		sprintf(str_buf, "invalid ID=%d (%s)", id, id2str(id));
		throwException(env, UNREGISTERED_SCANNER_EXCEPTION, str_buf);
		return;
	}

	if (native_protocols[id] == NULL) {
		
		sprintf(str_buf, "native scanner not registered under ID=%d (%s)", 
				id,
				id2str(id));
		throwException(env, UNREGISTERED_SCANNER_EXCEPTION,	str_buf);
		return;
	}

	setJMemoryPhysical(env, obj, toLong((void *)native_protocols[id]));
}
コード例 #5
0
/**
 * Scan packet buffer
 */
int scan(JNIEnv *env, jobject obj, jobject jpacket, scanner_t *scanner,
		packet_state_t *p_packet, int first_id, char *buf, int buf_len,
		uint32_t wirelen) {

	scan_t scan; // Our current in progress scan's state information
	scan_t *pscan = &scan;
	scan.env = env;
	scan.jscanner = obj;
	scan.jpacket = jpacket;
	scan.scanner = scanner;
	scan.packet = p_packet;
	scan.header = &p_packet->pkt_headers[0];
	scan.buf = buf;
	scan.buf_len = buf_len; // Changing buffer length, reduced by 'postfix'
	scan.mem_len = buf_len; // Constant in memory buffer length
	scan.wire_len = wirelen;
	scan.offset = 0;
	scan.length = 0;
	scan.id = first_id;
	scan.next_id = PAYLOAD_ID;
	scan.flags = 0;
	scan.stack_index = 0;

	scan.hdr_count = 0;
	scan.hdr_flags = 0;
	scan.hdr_prefix = 0;
	scan.hdr_gap = 0;
	scan.hdr_payload = 0;
	scan.hdr_postfix = 0;

	memset(scan.header, 0, sizeof(header_t));

	// Point jscan 
	setJMemoryPhysical(env, scanner->sc_jscan, toLong(&scan));

	// Local temp variables
	register uint64_t mask;

#ifdef DEBUG
	debug_enter("scan");
	debug_trace("processing packet", "#%d", p_packet->pkt_frame_num);
#endif

	/*
	 * Main scanner loop, 1st scans for builtin header types then
	 * reverts to calling on JBinding objects to provide the binding chain
	 */
	while (scan.id != END_OF_HEADERS) {
#ifdef DEBUG
		debug_trace("", "");
		debug_trace("processing header", id2str(scan.id));
		debug_scan("loop-top", &scan);
#endif

		/* A flag that keeps track of header recording. Set in record_header()*/
		scan.is_recorded = 0;

		/*
		 * If debugging is compiled in, we can also call on each protocols
		 * debug_* function to print out details about the protocol header
		 * structure. 
		 */
#ifdef DEBUG
		if (native_debug[scan.id]) {
			native_debug[scan.id](scan.buf + scan.offset);
		}
#endif

		/* 
		 * Scan of each protocol is done through a dispatch function table.
		 * Each protocol that has a protocol header scanner attached, a scanner
		 * designed specifically for that protocol. The protocol id is also the
		 * index into the table. There are 2 types of scanners both have exactly
		 * the same signature and thus both are set in this table. The first is
		 * the native scanner that only performs a direct scan of the header.
		 * The second scanner is a java header scanner. It is based on 
		 * JHeaderScanner class. A single dispatch method callJavaHeaderScanner
		 * uses the protocol ID to to dispatch to the appropriate java scanner.
		 * Uses a separate java specific table: sc_java_header_scanners[]. The
		 * java scanner is capable of calling the native scan method from java
		 * but also adds the ability to check all the attached JBinding[] for
		 * any additional registered bindings. Interesting fact is that if the
		 * java scanner doesn't have any bindings nor does it override the 
		 * default scan method to perform a scan in java and is also setup to 
		 * dispatch to native scanner, it is exactly same thing as if the 
		 * native scanner was dispatched directly from here, but round 
		 * about way through java land.
		 */
		if (scanner->sc_scan_table[scan.id] != NULL) {
			scanner->sc_scan_table[scan.id](&scan); // Dispatch to scanner
		}

#ifdef DEBUG
		debug_scan("loop-middle", &scan);
#endif

		if (scan.length == 0) {
#ifdef DEBUG
			debug_scan("loop-length==0", &scan);
#endif
			if (scan.id == PAYLOAD_ID) {
				if (scan.stack_index == 0) {
					scan.next_id = END_OF_HEADERS;
				} else {
					scan.stack_index --;
					scan.next_id = scan.stack[scan.stack_index].next_id;
					scan.offset = scan.stack[scan.stack_index].offset;
				}
			} else {
				scan.next_id = PAYLOAD_ID;
			}

		} else { // length != 0

#ifdef DEBUG
			debug_scan("loop-length > 0", &scan);
#endif

			/******************************************************
			 * ****************************************************
			 * * If override flag is set, then we reset the
			 * * discovered next protocol. If that is what the user 
			 * * wants then that is what he gets.
			 * ****************************************************
			 ******************************************************/
			if (scanner->sc_flags[scan.id] & FLAG_OVERRIDE_BINDING) {
#ifdef DEBUG
				debug_scan("TCP OVERRIDE", &scan);
#endif
				scan.next_id = PAYLOAD_ID;
			}

			/******************************************************
			 * ****************************************************
			 * * Now do HEURISTIC discovery scans if the appropriate
			 * * flags are set. Heuristics allow us to provide nxt
			 * * protocol binding, using discovery (an educated 
			 * * guess). 
			 * ****************************************************
			 ******************************************************/
			if (scanner->sc_flags[scan.id] & FLAG_HEURISTIC_BINDING) {

				/* 
				 * Save these critical properties, in case heuristic changes them
				 * for this current header, not the next one its supposed to
				 * check for.
				 */
				int saved_offset = scan.offset;
				int saved_length = scan.length;

				/* Advance offset to next header, so that heuristics can get a 
				 * peek. It will be restored at the end of heuristics block.
				 */
				scan.offset += scan.length + scan.hdr_gap;

				/*
				 * 2 types of heuristic bindings. Pre and post.
				 * Pre - heuristics are run before the direct discovery method
				 *       in scanner. Only after the pre-heuristic fail do we
				 *       utilize the directly discovered binding.
				 * 
				 * Post - heuristics are run after the direct discovery method
				 *        didn't produce a binding.
				 *
				 * ------------------------------------------------------------
				 * 
				 * In our case, since we have already ran the direct discovery
				 * in the header scanner, we save scan.next_id value, reset it,
				 * call the heuristic function, check its scan.next_id if it
				 * was set, if it was, then use that instead. Otherwise if it
				 * wasn't restore the original next_id and continue on normally.
				 */
				if (scanner->sc_flags[scan.id] & FLAG_HEURISTIC_PRE_BINDING) {
#ifdef DEBUG
					debug_scan("heurists_pre", &scan);
#endif

					int saved_next_id = scan.next_id;
					scan.next_id = PAYLOAD_ID;

					for (int i = 0; i < MAX_ID_COUNT; i++) {
						native_validate_func_t validate_func;
						validate_func
								= scanner->sc_heuristics_table[scan.id][i];

						if (validate_func == NULL) {
							break;
						}

						if ((scan.next_id = validate_func(&scan)) != INVALID) {
							break;
						}
					}

					if (scan.next_id == PAYLOAD_ID) {
						scan.next_id = saved_next_id;
					}

				} else if (scan.next_id == PAYLOAD_ID) {
#ifdef DEBUG
					debug_scan("heurists_post", &scan);
#endif
					for (int i = 0; i < MAX_ID_COUNT; i++) {
						native_validate_func_t validate_func;
						validate_func
								= scanner->sc_heuristics_table[scan.id][i];

						if (validate_func == NULL) {
							break;
						}

#ifdef DEBUG
						debug_trace("heurists_post", "[%d]", i);
#endif
						if ((scan.next_id = validate_func(&scan)) != INVALID) {

#ifdef DEBUG
							debug_scan("heurists_post::found", &scan);
#endif

							break;
						}
					}
				}

				/* Restore these 2 critical properties */
				scan.offset = saved_offset;
				scan.length = saved_length;
			}

			/******************************************************
			 * ****************************************************
			 * * Now record discovered information in structures
			 * ****************************************************
			 ******************************************************/
			record_header(&scan);

#ifdef DEBUG
			debug_header("header_t", scan.header - 1);
#endif
		} // End if len != 0

#ifdef DEBUG
		debug_scan("loop-bottom", &scan);
#endif

		scan.id = scan.next_id;
		scan.offset += scan.length + scan.hdr_gap;
		scan.length = 0;
		scan.next_id = PAYLOAD_ID;

		if (scan.offset >= scan.buf_len) {
			scan.id = END_OF_HEADERS;
		}

	} // End for loop

	/* record number of header entries found */
	//	scan.packet->pkt_header_count = count;

	process_flow_key(&scan);

#ifdef DEBUG
	debug_trace("loop-finished",
			"header_count=%d offset=%d header_map=0x%X",
			scan.packet->pkt_header_count, scan.offset,
			scan.packet->pkt_header_map);
	debug_exit("scan()");
#endif

	return scan.offset;
} // End scan()