www.pudn.com > tdi_fw.zip > disp_dg.c
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs) // // $Id: disp_dg.c,v 1.3 2002/11/11 12:38:54 dev Exp $ /* * This file contains TDI_SEND_DATAGRAM and TDI_RECEIVE_DATAGRAM handlers */ #include#include #include "sock.h" #include "dispatch.h" #include "filter.h" #include "memtrack.h" #include "obj_tbl.h" #include "tdi_fw.h" static NTSTATUS tdi_receive_datagram_complete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context); //---------------------------------------------------------------------------- /* * TDI_SEND_DATAGRAM handler */ int tdi_send_datagram(PIRP irp, PIO_STACK_LOCATION irps, struct completion *completion) { TDI_REQUEST_KERNEL_SENDDG *param = (TDI_REQUEST_KERNEL_SENDDG *)(&irps->Parameters); TA_ADDRESS *local_addr, *remote_addr; NTSTATUS status; struct ot_entry *ote_addr = NULL; KIRQL irql; int result = FILTER_DENY, ipproto; struct flt_request request; struct flt_rule rule; // check device object: UDP or RawIP if (get_original_devobj(irps->DeviceObject, &ipproto) == NULL || (ipproto != IPPROTO_UDP && ipproto != IPPROTO_IP)) { // unknown device object! KdPrint(("[tdi_fw] tdi_send_datagram: unknown DeviceObject 0x%x!\n", irps->DeviceObject)); goto done; } // sanity check if (param->SendLength >= 0x10000) { KdPrint(("[tdi_fw] tdi_send_datagram: datagram too big! (%u)\n", param->SendLength)); goto done; } // get local address of address object ote_addr = ot_find_fileobj(irps->FileObject, &irql); if (ote_addr == NULL) { KdPrint(("[tdi_fw] tdi_send_datagram: ot_find_fileobj(0x%x)!\n", irps->FileObject)); #if DBG // address object was created before driver was started result = FILTER_ALLOW; #endif goto done; } KdPrint(("[tdi_fw] tdi_send_datagram: addrobj 0x%x (size: %u)\n", irps->FileObject, param->SendLength)); local_addr = (TA_ADDRESS *)(ote_addr->local_addr); remote_addr = ((TRANSPORT_ADDRESS *)(param->SendDatagramInformation->RemoteAddress))->Address; KdPrint(("[tdi_fw] tdi_send_datagram(pid:%u): %x:%u -> %x:%u\n", ote_addr->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))); memset(&request, 0, sizeof(request)); request.struct_size = sizeof(request); request.type = TYPE_DATAGRAM; request.direction = DIRECTION_OUT; request.proto = ipproto; request.pid = ote_addr->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 (rule.log) log_request(&request); done: // cleanup if (ote_addr != NULL) KeReleaseSpinLock(&g_ot_hash_guard, irql); return result; } //---------------------------------------------------------------------------- /* * TDI_RECEIVE_DATAGRAM handler */ int tdi_receive_datagram(PIRP irp, PIO_STACK_LOCATION irps, struct completion *completion) { KdPrint(("[tdi_fw] tdi_receive_datagram: addrobj 0x%x\n", irps->FileObject)); completion->routine = tdi_receive_datagram_complete; completion->context = irps->FileObject; return FILTER_ALLOW; } NTSTATUS tdi_receive_datagram_complete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { PIO_STACK_LOCATION irps = IoGetCurrentIrpStackLocation(Irp); TDI_REQUEST_KERNEL_RECEIVEDG *param = (TDI_REQUEST_KERNEL_RECEIVEDG *)(&irps->Parameters); PFILE_OBJECT addrobj = (PFILE_OBJECT)irps->FileObject; struct ot_entry *ote_addr = NULL; KIRQL irql; int result = FILTER_DENY, ipproto; NTSTATUS status = STATUS_SUCCESS; struct flt_request request; struct flt_rule rule; TA_ADDRESS *local_addr, *remote_addr; // check device object: UDP or RawIP if (get_original_devobj(DeviceObject, &ipproto) == NULL || (ipproto != IPPROTO_UDP && ipproto != IPPROTO_IP)) { // unknown device object! KdPrint(("[tdi_fw] tdi_receive_datagram_complete: unknown DeviceObject 0x%x!\n", DeviceObject)); status = STATUS_UNSUCCESSFUL; goto done; } KdPrint(("[tdi_fw] tdi_receive_datagram_complete: addrobj 0x%x; status 0x%x; information %u\n", addrobj, Irp->IoStatus.Status, Irp->IoStatus.Information)); if (Irp->IoStatus.Status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_receive_datagram_complete: status 0x%x\n", Irp->IoStatus.Status)); status = Irp->IoStatus.Status; goto done; } ote_addr= ot_find_fileobj(addrobj, &irql); if (ote_addr == NULL) { KdPrint(("[tdi_fw] tdi_receive_datagram_complete: ot_find_fileobj(0x%x)!\n", addrobj)); status = STATUS_UNSUCCESSFUL; goto done; } memset(&request, 0, sizeof(request)); request.struct_size = sizeof(request); request.type = TYPE_DATAGRAM; request.direction = DIRECTION_IN; request.proto = ipproto; request.pid = ote_addr->pid; local_addr = (TA_ADDRESS *)(ote_addr->local_addr); remote_addr = ((TRANSPORT_ADDRESS *)(param->ReceiveDatagramInformation->RemoteAddress))->Address; KdPrint(("[tdi_fw] tdi_receive_datagram_complete(pid:%u): %x:%u -> %x:%u\n", ote_addr->pid, ntohl(((TDI_ADDRESS_IP *)(remote_addr->Address))->in_addr), ntohs(((TDI_ADDRESS_IP *)(remote_addr->Address))->sin_port), ntohl(((TDI_ADDRESS_IP *)(local_addr->Address))->in_addr), ntohs(((TDI_ADDRESS_IP *)(local_addr->Address))->sin_port))); memcpy(&request.addr.from, &remote_addr->AddressType, sizeof(struct sockaddr)); memcpy(&request.addr.to, &local_addr->AddressType, sizeof(struct sockaddr)); request.addr.len = sizeof(struct sockaddr_in); memset(&rule, 0, sizeof(rule)); result = quick_filter(&request, &rule); if (rule.log) log_request(&request); done: // convert result to NTSTATUS if (result == FILTER_ALLOW) status = STATUS_SUCCESS; else { /* FILTER_DENY */ if (status == STATUS_SUCCESS) { status = STATUS_ACCESS_VIOLATION; Irp->IoStatus.Status = STATUS_ACCESS_VIOLATION; } } // cleanup if (ote_addr != NULL) KeReleaseSpinLock(&g_ot_hash_guard, irql); return status; }