⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disp_conn.c

📁 基于TDI驱动编写的个人防火墙程序。包括驱动模块、应用层规则配置及加载模块。
💻 C
字号:
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// $Id: disp_conn.c,v 1.2 2002/10/01 12:54:15 dev Exp $

/*
 * This file contains TDI_CONNECT handler
 */

#include <ntddk.h>
#include <tdikrnl.h>
#include "sock.h"

#include "dispatch.h"
#include "events.h"
#include "memtrack.h"
#include "obj_tbl.h"
#include "tdi_fw.h"

//----------------------------------------------------------------------------

/*
 * TDI_CONNECT handler
 */

int
tdi_connect(PIRP irp, PIO_STACK_LOCATION irps, struct completion *completion)
{
	PTDI_REQUEST_KERNEL_CONNECT param = (PTDI_REQUEST_KERNEL_CONNECT)(&irps->Parameters);
	TA_ADDRESS *remote_addr = ((TRANSPORT_ADDRESS *)(param->RequestConnectionInformation->RemoteAddress))->Address;
	PFILE_OBJECT addrobj;
	NTSTATUS status;
	TA_ADDRESS *local_addr;
	int result = FILTER_DENY, ipproto;
	struct ot_entry *ote_conn = NULL, *ote_addr;
	KIRQL irql;
	struct flt_request request;
	struct flt_rule rule;

	KdPrint(("[tdi_fw] tdi_connect: connobj 0x%x, to address %x:%u\n",
		irps->FileObject,
		ntohl(((TDI_ADDRESS_IP *)(remote_addr->Address))->in_addr),
		ntohs(((TDI_ADDRESS_IP *)(remote_addr->Address))->sin_port)));

	// check device object: TCP or UDP
	if (irps->DeviceObject != g_tcpfltobj && irps->DeviceObject != g_udpfltobj) {
		KdPrint(("[tdi_fw] tdi_connect: unknown DeviceObject 0x%x\n", irps->DeviceObject));
		goto done;
	}

	ote_conn = ot_find_fileobj(irps->FileObject, &irql);
	if (ote_conn == NULL) {
		KdPrint(("[tdi_fw] tdi_connect: ot_find_fileobj(0x%x)\n", irps->FileObject));
		goto done;
	}

	if (get_original_devobj(irps->DeviceObject, &ipproto) == NULL ||
		(ipproto != IPPROTO_TCP && ipproto != IPPROTO_UDP)) {
		// invalid device object!
		KdPrint(("[tdi_fw] tdi_connect: invalid device object 0x%x\n", irps->DeviceObject));
		goto done;
	}

	if (ipproto == IPPROTO_TCP) {
		/*
		 * For TCP: get addrobj by connobj and get local address by it
		 */

		addrobj = ote_conn->associated_fileobj;
		if (addrobj == NULL) {
			KdPrint(("[tdi_fw] tdi_connect: empty addrobj!\n"));
			goto done;
		}

		ote_addr = ot_find_fileobj(addrobj, NULL); // we're already in spinlock
		if (ote_conn == NULL) {
			KdPrint(("[tdi_fw] tdi_connect: ot_find_fileobj(0x%x)\n", addrobj));
			goto done;
		}

	} else {
		/*
		 * For UDP: connobj and addrobj are the same
		 */
		KdPrint(("[tdi_fw] tdi_connect: connected UDP socket detected\n"));

		// for connected UDP sockets connobj and addrobj are the same
		addrobj= irps->FileObject;
		ote_addr = ote_conn;
	}

	local_addr = (TA_ADDRESS *)(ote_addr->local_addr);

	// sanity check
	if (local_addr->AddressLength != remote_addr->AddressLength) {
		KdPrint(("[tdi_fw] tdi_connect: different addr lengths! (%u != %u)\n",
			local_addr->AddressLength, remote_addr->AddressLength));
		goto done;
	}

	// set remote address with connobj
	
	if (remote_addr->AddressLength > sizeof(ote_conn->remote_addr)) {
		KdPrint(("[tdi_fw] tdi_connect: address too long! (%u)\n", remote_addr->AddressLength));
		goto done;
	}
	memcpy(ote_conn->remote_addr, remote_addr, remote_addr->AddressLength);

	// set local address with connobj

	if (local_addr->AddressLength > sizeof(ote_conn->local_addr)) {
		KdPrint(("[tdi_fw] tdi_connect: address to long! (%u)\n", local_addr->AddressLength));
		goto done;
	}
	memcpy(ote_conn->local_addr, local_addr, local_addr->AddressLength);

	KdPrint(("[tdi_fw] tdi_connect(pid:%u): %x:%u -> %x:%u (ipproto = %d)\n",
		ote_conn->pid,
		ntohl(((TDI_ADDRESS_IP *)(local_addr->Address))->in_addr),
		ntohs(((TDI_ADDRESS_IP *)(local_addr->Address))->sin_port),
		ntohl(((TDI_ADDRESS_IP *)(remote_addr->Address))->in_addr),
		ntohs(((TDI_ADDRESS_IP *)(remote_addr->Address))->sin_port), ipproto));

	/*
	 * Call quick_filter
	 */

	memset(&request, 0, sizeof(request));
	request.struct_size = sizeof(request);

	request.type = TYPE_CONNECT;
	request.direction = DIRECTION_OUT;
	request.proto = ipproto;
	request.pid = ote_conn->pid;
	
	memcpy(&request.addr.from, &local_addr->AddressType, sizeof(struct sockaddr));
	memcpy(&request.addr.to, &remote_addr->AddressType, sizeof(struct sockaddr));
	request.addr.len = sizeof(struct sockaddr_in);

	memset(&rule, 0, sizeof(rule));

	result = quick_filter(&request, &rule);

	// if logging is needed log request
	if (rule.log)
		log_request(&request);

done:
	// cleanup
	if (ote_conn != NULL)
		KeReleaseSpinLock(&g_ot_hash_guard, irql);

	return result;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -