Re: TDI driver event queueing
From: serge (pserge77_at_ukr.net)
Date: 02/10/05
- Next message: bacardiman: "Print Port Monitor - garbled port name"
- Previous message: Gary G. Little: "Re: Can we load a .sys file from another .sys file"
- In reply to: Steve: "Re: TDI driver event queueing"
- Next in thread: Maxim S. Shatskih: "Re: TDI driver event queueing"
- Reply: Maxim S. Shatskih: "Re: TDI driver event queueing"
- Messages sorted by: [ date ] [ thread ]
Date: Thu, 10 Feb 2005 17:58:29 +0200
Hello, Steve!
S> Have you considered using an NDIS IM
S> driver and queueing packets instead?
This is already done :)
Probably you rememer my NDIS IM related questions here some weeks ago.
I want to allow/deny incoming and outgoing connections on user level.
I can do so on NDIS IM level, but there is one problem:
Process name is unknown when SYN packet arrives. I can not provide user with
application name that attempts to connect to remote host, or accepts
incoming connection.
I can see two solutions:
(1) wait until system replies with SYN+ACK. This will be done in process
context, so we can get it's name.
(2) filter connections on TDI level.
As for (1) - I am not sure about security. Probably it's not not safe to
allow application to receive stand-alone SYN packet. Also, it's not clear
how to drop connection in this case (application sent SYN+ACK will be
waiting for ACK packet(s) from remote host....)
Also, I feel that TDI queueing is not very simple task, and it even may not
work on all Windows builds...
Best regards,
Serge.
You wrote on Wed, 9 Feb 2005 17:49:32 -0800:
S> Firstly, your event is called by tcpip (when the event
S> occurrs) not by the kernel-mode client. You call the
S> kernel-mode client when you call the original handler
S> (which is the clients handler).
S> As for the BytesTaken and IoRequestPacket I am not sure
S> how you can deal with them. They are pointers to
S> variables that belong to tcpip. The client in its event
S> handler would read the data received and inform tcpip how
S> much it read in BytesTaken. Also, the client might
S> allocate an irp for IoRequestPacket, this irp would be
S> set up to receive any more available data. What you are
S> attempting to do is very difficult. If your filter does
S> nothing with BytesTaken and IoRequestPacket tcpip will
S> assume that the client is not interested in the received
S> data! You will have to process this event as if you were
S> the client, i.e. read all data and set BytesTaken, and
S> create irp for IoRequestPacket. This gets even trickier
S> because then you will be responsible for this irp - you
S> will need to register a completion routine for it, etc.
S> When you dequeue and call the original client handler you
S> will have to look and behave like tcpip, i.e. process any
S> irp the client gives you in IoRequestPacket (i.e. copy
S> data from the irp your filter created).
S> Filtering in the tdi is very complicated, as you are
S> finding. You are the middle man, to the client you must
S> look and act like tcpip, to tcpip you must look and act
S> like the client. Have you considered using an NDIS IM
S> driver and queueing packets instead?
S> Steve.
>> -----Original Message-----
>> Hello, Steve!
>>
>> I already created transparent TDI driver that filters
S> all the events and
>> requests, so now I am moving towards queueing. Yes, I
S> have seen tdi_fw
>> sources, thay are great as a start point.
>>
>> I can not understand one thing:
>> When kernel-mode client sends event to my TDI driver,
S> does it want to get
>> reply immediately?
>> I can save input variables, and then call original event
S> handler in my
>> worker thread, but what about output variables?
>>
>> In our example parameters BytesTaken and IoRequestPacket
S> are output one.
>> Can I save these pointers and use them in my thread
S> later?
>> Are these variables located in static memory?
>> I afraid I will receive BSOD when I try to write there
S> something there from
>> my thread...
>>
>> Best regards,
>> Serge.
>>
>> You wrote on Wed, 9 Feb 2005 16:27:47 -0800:
>>
S>>> TdiEventContext is the context that you supplied in
S> the
S>>> filter function for TDI_SET_EVENT_HANDLER. If you
S> look at
S>>> the example I gave you TdiEventContext is ...
S>>> EventContext *filteredCtx;
>>
S>>> You use this value to get back the original context
S> and
S>>> handler. If you call the original handler within
S> your
S>>> filtered handler your code will look something like
S>>> this ...
>>
S>>> EventContext *ctx = (EventContext*)TdiEventContext;
>>
S>>> // call old handler with old context
S>>> //
S>>> return ((PTDI_IND_RECEIVE_DATAGRAM)(ctx-
>> oldEventHandler))
S>>> (ctx->oldEventContext,
S>>> SourceAddressLength,
S>>> SourceAddress,
S>>> OptionsLength,
S>>> Options,
S>>> ReceiveDatagramFlags,
S>>> BytesIndicated,
S>>> BytesAvailable,
S>>> BytesTaken,
S>>> Tsdu,
S>>> IoRequestPacket);
>>
S>>> I recommend that you firstly get the code working
S> without
S>>> queueing (i.e. call the original handler immediately
S> in
S>>> your filtered handler) ... this way you can ensure
S> your
S>>> filters are working correctly. Move on to queueing
S>>> after ... this is something I have not tried so you
S> will
S>>> have to work that out. The help on
S>>> ClientEventReceiveDatagram should answer most of your
S>>> other questions.
>>
S>>> There is a great example tdi firewall called tdi_fw
S> that
S>>> you should try to download
S>>> http://sourceforge.net/projects/tdifw.
>>
S>>> ps. you might have noticed there is a small bug in
S> the
S>>> example ...
S>>> filteredCtx = ExAllocatePool(NonPagedPool, sizeof
S>>> (TDI_EVENT_CONTEXT));
>>
S>>> This should be ...
S>>> filteredCtx = ExAllocatePool(NonPagedPool, sizeof
S>>> (EventContext));
>>
S>>> Steve
>>
>>>> -----Original Message-----
>>>> Hello, Steve!
>>>>
>>>> Thanks for the reply.
>>>> There are several moments that are not crear for me.
>>>> Almost all event callback functions have pointers as
S>>> input parameters.
>>>> Do they point to static memory? Can I simply store
S>>> pointers, or I must
>>>> allocate memory and copy original one?
>>>>
>>>> Can you clarify the following:
>>>>
>>>> //
>>>> // the callback function set via
S> TDI_SET_EVENT_HANDLER
>>>> //
>>>> NTSTATUS tdi_event_receive_datagram(
>>>> //
>>>> // ** I do not know memory size pointed by
S>>> TdiEventContext
>>>> IN PVOID TdiEventContext,
>>>> IN LONG SourceAddressLength,
>>>> IN PVOID SourceAddress,
>>>> IN LONG OptionsLength,
>>>> IN PVOID Options,
>>>> IN ULONG ReceiveDatagramFlags,
>>>> IN ULONG BytesIndicated,
>>>> IN ULONG BytesAvailable,
>>>> //
>>>> // ** does it point to static variable?
>>>> OUT ULONG *BytesTaken,
>>>> //
>>>> // ** memory size pointed by Tsdu is unknown?
>>>> IN PVOID Tsdu,
>>>> //
>>>> // ** do I need to store the pointer or the value?
>>>> OUT PIRP *IoRequestPacket)
>>>> {
>>>>
>>>> // adding to queue all the input parameters;
>>>>
>>>> //
>>>> // what value should I return exactly?
>>>> //
>>>> return STATUS_PENDING;
>>>> }
>>>>
>>>> void MyThread()
>>>> {
>>>> // here I will call old original event handler
>>>> // with parameters previously stored in queue.
>>>> // and then release allocated memory.
>>>> }
>>>>
>>>> Best regards,
>>>> Serge.
>>>>
>>>> You wrote on Tue, 8 Feb 2005 18:25:23 -0800:
>>>>
S>>>>> Firstly, you will need to filter the events. With
S>>>>> filtering in place, when an event is triggered on
S> an
S>>>>> address object your event filter function will get
S>>>>> called, and then you can call the original event
S>>>>> function, either immediately, or later if you are
S>>>>> queueing.
>>>>
S>>>>> To setup filtering events you must first filter the
S>>>>> handler for TDI_SET_EVENT_HANDLER (as you filter
S> any
S>>>>> other IRP). A client that wants to register an
S> event
S>>>>> will send a TDI_SET_EVENT_HANDLER irp for a
S>>> particular
S>>>>> address object. This irp will contain an event
S> type,
S>>>>> handler and context. Here you patch in your
S> handler
S>>> (and
S>>>>> context) and store away the original handler and
S>>>>> context. You will need the original values so that
S>>> when
S>>>>> your event handler is called, you can then call the
S>>>>> original handler. A typical way to store the
S>>>>> originalvalues is to store them in your own event
S>>> context.
>>>>
S>>>>> Here is an example handler for
S>>> TDI_SET_EVENT_HANDLER ...
>>>>
S>>>>> typedef struct
S>>>>> {
S>>>>> PFILE_OBJECT fileobj; // address object
S>>>>> PVOID oldEventHandler;
S>>>>> PVOID oldEventContext;
>>>>
S>>>>> } EventContext;
>>>>
S>>>>> // -----------------------------------------------
S> --
S>>> -----
S>>>>> ----------------------
S>>>>> void SetEventHandler(PIRP irp, PIO_STACK_LOCATION
S>>> irps)
S>>>>> {
S>>>>> PTDI_REQUEST_KERNEL_SET_EVENT event =
S>>>>> (PTDI_REQUEST_KERNEL_SET_EVENT)&irps->Parameters;
S>>>>> EventContext *filteredCtx;
>>>>
S>>>>> filteredCtx = ExAllocatePool(NonPagedPool, sizeof
S>>>>> (TDI_EVENT_CONTEXT));
>>>>
S>>>>> // store original (client supplied) data
S>>>>> //
S>>>>> filteredCtx->fileobj = irps->FileObject; //
S>>> address
S>>>>> object
S>>>>> filteredCtx->oldEventHandler = event-
>> EventHandler;
S>>>>> filteredCtx->oldEventContext = event-
>> EventContext;
>>>>
S>>>>> // patch in our data
S>>>>> //
S>>>>> event->EventHandler = filteredEventHandler; //
S>>> this
S>>>>> must point to a function
S>>>>> //
S>>> that
S>>>>> has the same definition
S>>>>> //
S> as
S>>> the
S>>>>> event function you are
S>>>>> //
S>>>>> filtering
S>>>>> event->EventContext = filteredCtx;
>>>>
S>>>>> // now send IRP on down to lower driver ...
S>>>>> }
>>>>
S>>>>> If you need more help email me.
S>>>>> Steve.
>>>>
>>>>>> -----Original Message-----
>>>>>> Hello,
>>>>>>
>>>>>> I can save IRP requests, and complete/cancel them
S>>> later
S>>>>> successfully.
>>>>>> But I want to queue events, set by
S>>> TDI_SET_EVENT_HANDLER
S>>>>> as well.
>>>>>>
>>>>>> Could anybody clarify how this can be done?
>>>>>>
>>>>>> Thanks!
>>>>>>
>>>>>> Best regards,
>>>>>> Serge.
- Next message: bacardiman: "Print Port Monitor - garbled port name"
- Previous message: Gary G. Little: "Re: Can we load a .sys file from another .sys file"
- In reply to: Steve: "Re: TDI driver event queueing"
- Next in thread: Maxim S. Shatskih: "Re: TDI driver event queueing"
- Reply: Maxim S. Shatskih: "Re: TDI driver event queueing"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|