www.pudn.com > tdi_fw.zip > disp_conn.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#include #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; }