summaryrefslogtreecommitdiff
path: root/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'network.c')
-rw-r--r--network.c715
1 files changed, 715 insertions, 0 deletions
diff --git a/network.c b/network.c
new file mode 100644
index 0000000..3564db2
--- /dev/null
+++ b/network.c
@@ -0,0 +1,715 @@
1/*
2 * Copyright (c) 2004 Security Architects Corporation. All rights reserved.
3 *
4 * Module Name:
5 *
6 * network.c
7 *
8 * Abstract:
9 *
10 * This module defines various routines used for hooking the Transport Driver Interface (TDI) network routines.
11 *
12 * Author:
13 *
14 * Eugene Tsyrklevich 12-Mar-2004
15 *
16 * Revision History:
17 *
18 * None.
19 */
20
21
22#include <NTDDK.h>
23#include <tdikrnl.h>
24#include <ctype.h>
25#include "network.h"
26#include "hookproc.h"
27#include "userland.h"
28#include "learn.h"
29#include "policy.h"
30#include "log.h"
31
32
33#ifdef ALLOC_PRAGMA
34#pragma alloc_text (INIT, InstallNetworkHooks)
35#pragma alloc_text (PAGE, RemoveNetworkHooks)
36#endif
37
38
39//XXX fast io is not handled. TdiDispatchFastDeviceControl
40
41
42PDEVICE_OBJECT pTcpDevice = NULL, pTcpDeviceOriginal = NULL;
43PDEVICE_OBJECT pUdpDevice = NULL, pUdpDeviceOriginal = NULL;
44PDEVICE_OBJECT pIpDevice = NULL, pIpDeviceOriginal = NULL;
45
46#if DBG
47int HookedTDIRunning = 0;
48#endif
49
50
51/*
52 * TdiStub() XXX remove
53 *
54 * Description:
55 * .
56 *
57 * Parameters:
58 * pIrp - IRP (I/O Request Packet) request.
59 * pIrpStack - .
60 * pCompletion - .
61 *
62 * Returns:
63 * STATUS_SUCCESS.
64 */
65
66NTSTATUS
67TdiStub(IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpStack, OUT PTDI_CALLBACK pCompletion, IN ULONG DeviceType)
68{
69// LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("TdiStub(%x %x %x)\n", pIrp, pIrpStack, pCompletion));
70 return STATUS_SUCCESS;
71}
72
73
74
75NTSTATUS
76TdiSetEventHandler(IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpStack, OUT PTDI_CALLBACK pCompletion, IN ULONG DeviceType)
77{
78 PTDI_REQUEST_KERNEL_SET_EVENT r = (PTDI_REQUEST_KERNEL_SET_EVENT) &pIrpStack->Parameters;
79
80
81 if (r->EventType != TDI_EVENT_CONNECT)
82 {
83 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("%d TdiSetEventHandler: %x %x %x\n", CURRENT_PROCESS_PID, r->EventType, r->EventHandler, r->EventContext));
84 return STATUS_SUCCESS;
85 }
86
87
88 if (r->EventHandler == NULL)
89 {
90 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("%d TdiSetEventHandler: TDI_EVENT_CONNECT deregistration %x %x %x\n", CURRENT_PROCESS_PID, r->EventHandler, r->EventContext, pIrpStack->FileObject));
91 return STATUS_SUCCESS;
92 }
93
94
95 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("%d TdiSetEventHandler: TDI_EVENT_CONNECT %x %x %x\n", CURRENT_PROCESS_PID, r->EventHandler, r->EventContext, pIrpStack->FileObject));
96
97
98 return STATUS_SUCCESS;
99}
100
101
102
103NTSTATUS
104TdiConnect(IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpStack, OUT PTDI_CALLBACK pCompletion, IN ULONG DeviceType)
105{
106 /*
107 * IrpSp->Parameters
108 *
109 * Pointer to a TDI_REQUEST_KERNEL_CONNECT structure, equivalent to the TDI_REQUEST_KERNEL structure.
110 */
111
112 PTDI_REQUEST_KERNEL_CONNECT ConnectInfo = (PTDI_REQUEST_KERNEL_CONNECT) &pIrpStack->Parameters;
113 PTRANSPORT_ADDRESS pTransportAddress;
114 PTA_ADDRESS pAddress;
115 PTDI_ADDRESS_IP ip;
116 CHAR NETWORKNAME[MAX_PATH];
117 PCHAR FunctionName = "TdiConnect";
118
119
120 HOOK_ROUTINE_ENTER();
121
122
123 if (! MmIsAddressValid(ConnectInfo) ||
124 ! MmIsAddressValid(ConnectInfo->RequestConnectionInformation) ||
125 ! MmIsAddressValid(ConnectInfo->RequestConnectionInformation->RemoteAddress))
126 {
127 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("TdiConnect: MmIsAddressValid failed\n"));
128 HOOK_ROUTINE_EXIT(STATUS_SUCCESS);
129 }
130
131
132 pTransportAddress = (PTRANSPORT_ADDRESS) ConnectInfo->RequestConnectionInformation->RemoteAddress;
133
134 pAddress = (PTA_ADDRESS) pTransportAddress->Address;
135
136 /* verify that the specified address is a single IP address */
137 if (pTransportAddress->TAAddressCount != 1 ||
138 pAddress->AddressType != TDI_ADDRESS_TYPE_IP ||
139 pAddress->AddressLength != TDI_ADDRESS_LENGTH_IP)
140 {
141 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("%d TdiConnect: Invalid address detected\n", CURRENT_PROCESS_PID));
142 HOOK_ROUTINE_EXIT(STATUS_SUCCESS);
143 }
144
145 ip = (PTDI_ADDRESS_IP) &pAddress->Address;
146
147
148 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("%d TdiConnect(%x %x %x). %d %x:%u (%s)\n", (ULONG) PsGetCurrentProcessId(), pIrp, pIrpStack, pCompletion, pTransportAddress->TAAddressCount, ntohl(ip->in_addr), ntohs(ip->sin_port), inet_ntoa2(ip->in_addr)));
149
150
151 inet_ntoa(ip->in_addr, NETWORKNAME);
152
153 if (LearningMode == FALSE)
154 {
155 POLICY_CHECK_OPTYPE_NAME(NETWORK, DeviceType == NET_DEVICE_TYPE_TCP ? OP_TCPCONNECT : OP_UDPCONNECT);
156 }
157 else
158 {
159 // learning mode
160 AddRule(RULE_NETWORK, NETWORKNAME, DeviceType == NET_DEVICE_TYPE_TCP ? OP_TCPCONNECT : OP_UDPCONNECT);
161 }
162
163
164 HOOK_ROUTINE_EXIT(STATUS_SUCCESS);
165}
166
167
168
169NTSTATUS
170TdiListen(IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpStack, OUT PTDI_CALLBACK pCompletion, IN ULONG DeviceType)
171{
172 /*
173 * IrpSp->Parameters
174 *
175 * Pointer to a TDI_REQUEST_KERNEL_LISTEN structure, equivalent to the TDI_REQUEST_KERNEL structure.
176 */
177
178 PTDI_REQUEST_KERNEL_LISTEN ListenInfo = (PTDI_REQUEST_KERNEL_LISTEN) &pIrpStack->Parameters;
179 PTRANSPORT_ADDRESS pTransportAddress;
180 PTA_ADDRESS pAddress;
181 PTDI_ADDRESS_IP ip;
182
183
184 if (! MmIsAddressValid(ListenInfo) ||
185 ! MmIsAddressValid(ListenInfo->RequestConnectionInformation) ||
186 ! MmIsAddressValid(ListenInfo->RequestConnectionInformation->RemoteAddress))
187 {
188 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("TdiListen: MmIsAddressValid failed\n"));
189 HOOK_ROUTINE_EXIT(STATUS_SUCCESS);
190 }
191
192 pTransportAddress = (PTRANSPORT_ADDRESS) ListenInfo->RequestConnectionInformation->RemoteAddress;
193
194 pAddress = (PTA_ADDRESS) pTransportAddress->Address;
195
196 /* verify that the specified address is a single IP address */
197 if (pTransportAddress->TAAddressCount != 1 ||
198 pAddress->AddressType != TDI_ADDRESS_TYPE_IP ||
199 pAddress->AddressLength != TDI_ADDRESS_LENGTH_IP)
200 {
201 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("%d TdiListen: Invalid address detected\n", CURRENT_PROCESS_PID));
202 HOOK_ROUTINE_EXIT(STATUS_SUCCESS);
203 }
204
205 ip = (PTDI_ADDRESS_IP) &pAddress->Address;
206
207
208 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("TdiListen(%x %x %x). %d %x:%u (%s)\n", pIrp, pIrpStack, pCompletion, pTransportAddress->TAAddressCount, ntohl(ip->in_addr), ntohs(ip->sin_port), inet_ntoa2(ip->in_addr)));
209
210
211 return STATUS_SUCCESS;
212}
213
214
215
216NTSTATUS
217TdiAccept(IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpStack, OUT PTDI_CALLBACK pCompletion, IN ULONG DeviceType)
218{
219 /*
220 * IrpSp->Parameters
221 *
222 * Specifies a TDI_REQUEST_KERNEL_ACCEPT structure.
223 */
224
225 PTDI_REQUEST_KERNEL_ACCEPT AcceptInfo = (PTDI_REQUEST_KERNEL_ACCEPT) &pIrpStack->Parameters;
226 PTRANSPORT_ADDRESS pTransportAddress = (PTRANSPORT_ADDRESS) AcceptInfo->RequestConnectionInformation->RemoteAddress;
227 PTA_ADDRESS pAddress = (PTA_ADDRESS) pTransportAddress->Address;
228 PTDI_ADDRESS_IP ip = (PTDI_ADDRESS_IP) &pAddress->Address;
229
230
231 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("TdiAccept(%x %x %x). %d %x:%u (%s)\n", pIrp, pIrpStack, pCompletion, pTransportAddress->TAAddressCount, ntohl(ip->in_addr), ntohs(ip->sin_port), inet_ntoa2(ip->in_addr)));
232
233
234 return STATUS_SUCCESS;
235}
236
237
238/*
239NTSTATUS
240GenericCompletion(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pContext)
241{
242 if (pIrp->PendingReturned )
243 IoMarkIrpPending(pIrp);
244
245 return STATUS_SUCCESS;
246}
247*/
248
249
250TDI_IOCTL TdiIoctl[] =
251{
252 { TDI_ASSOCIATE_ADDRESS, "TDI_ASSOCIATE_ADDRESS", TdiStub },
253 { TDI_DISASSOCIATE_ADDRESS, "TDI_DISASSOCIATE_ADDRESS", TdiStub },
254 { TDI_CONNECT, "TDI_CONNECT", TdiConnect },
255 { TDI_LISTEN, "TDI_LISTEN", TdiListen },
256 { TDI_ACCEPT, "TDI_ACCEPT", TdiAccept },
257 { TDI_DISCONNECT, "TDI_DISCONNECT", TdiStub },
258 { TDI_SEND, "TDI_SEND", TdiStub },
259 { TDI_RECEIVE, "TDI_RECEIVE", TdiStub },
260 { TDI_SEND_DATAGRAM, "TDI_SEND_DATAGRAM", TdiStub },
261 { TDI_RECEIVE_DATAGRAM, "TDI_RECEIVE_DATAGRAM", TdiStub },
262 { TDI_SET_EVENT_HANDLER, "TDI_SET_EVENT_HANDLER", TdiSetEventHandler },
263 { TDI_QUERY_INFORMATION, "TDI_QUERY_INFORMATION", TdiStub },
264 { TDI_SET_INFORMATION, "TDI_SET_INFORMATION", TdiStub },
265 { TDI_ACTION, "TDI_ACTION", TdiStub },
266 { TDI_DIRECT_SEND, "TDI_DIRECT_SEND", TdiStub },
267 { TDI_DIRECT_SEND_DATAGRAM, "TDI_DIRECT_SEND_DATAGRAM", TdiStub },
268};
269
270
271
272//XXX this function can be called from HookedNtCreateFile (-> NtCreateFile -> IoCreateFile -> ObOpenObjectbyName -> ... -> TDI)
273BOOLEAN
274TDIDispatch(PDEVICE_OBJECT pDeviceObject, PIRP pIrp, NTSTATUS *status)
275{
276 PIO_STACK_LOCATION pIrpStack;
277 TDI_CALLBACK Callback;
278 ULONG DeviceType = 0;
279
280
281 if (pDeviceObject == pTcpDevice)
282 {
283 DeviceType = NET_DEVICE_TYPE_TCP;
284 }
285 else if (pDeviceObject == pUdpDevice)
286 {
287 DeviceType = NET_DEVICE_TYPE_UDP;
288 }
289 else if (pDeviceObject == pIpDevice)
290 {
291 DeviceType = NET_DEVICE_TYPE_IP;
292 }
293 else
294 {
295 return FALSE;
296 }
297
298
299 HOOK_TDI_ENTER_NORC();
300
301
302 pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
303
304
305 memset(&Callback, 0, sizeof(Callback));
306
307// if (pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER)
308// {
309// LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER\n"));
310// }
311
312 switch (pIrpStack->MajorFunction)
313 {
314 case IRP_MJ_CREATE:
315
316 *status = TDICreate(pDeviceObject, pIrp, pIrpStack, &Callback);
317
318 break;
319
320
321 case IRP_MJ_DEVICE_CONTROL:
322
323// if (DeviceType == NET_DEVICE_TYPE_IP && pIrpStack->Parameters.DeviceIoControl.IoControlCode == 0x120000)
324 if (DeviceType == NET_DEVICE_TYPE_IP)
325 {
326 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("%d pIpDevice in use (%x %x %x)\n", (ULONG) PsGetCurrentProcessId(), pIrpStack->Parameters.DeviceIoControl.IoControlCode, pIrpStack->MajorFunction, pIrpStack->MinorFunction));
327// *status = STATUS_ACCESS_DENIED;
328 break;
329 }
330
331 if (KeGetCurrentIrql() != PASSIVE_LEVEL || ! NT_SUCCESS(TdiMapUserRequest(pDeviceObject, pIrp, pIrpStack)))
332 {
333 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("TdiMapUserRequest failed: %x (irql %d)\n", pIrpStack->Parameters.DeviceIoControl.IoControlCode, KeGetCurrentIrql()));
334 break;
335 }
336
337 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("IRP_MJ_DEVICE_CONTROL2 %x\n", pIrpStack->Parameters.DeviceIoControl.IoControlCode));
338
339 /* FALLTHROUGH */
340
341
342 case IRP_MJ_INTERNAL_DEVICE_CONTROL:
343 {
344 int i;
345
346 if (DeviceType == NET_DEVICE_TYPE_IP)
347 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("%d pIpDevice in use2\n", (ULONG) PsGetCurrentProcessId()));
348
349 for (i = 0; i < sizeof(TdiIoctl) / sizeof(TdiIoctl[0]); i++)
350 {
351 if (TdiIoctl[i].MinorFunction == pIrpStack->MinorFunction)
352 {
353 if (TdiIoctl[i].pfRoutine == TdiStub)
354 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("%d IRP_MJ_INTERNAL_DEVICE_CONTROL %s\n", (ULONG) PsGetCurrentProcessId(), TdiIoctl[i].Description));
355
356 *status = TdiIoctl[i].pfRoutine(pIrp, pIrpStack, &Callback, DeviceType);
357
358 break;
359 }
360 }
361
362 break;
363 }
364
365 case IRP_MJ_CLEANUP:
366 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("IRP_MJ_CLEANUP\n"));
367 break;
368
369 case IRP_MJ_CLOSE:
370 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("IRP_MJ_CLOSE\n"));
371 break;
372
373 default:
374 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("TDIDispatch: default switch case triggered\n"));
375 break;
376 }
377
378
379 if (*status == STATUS_ACCESS_DENIED)
380 {
381 pIrp->IoStatus.Status = STATUS_ACCESS_DENIED;
382 IoCompleteRequest (pIrp, IO_NO_INCREMENT);
383
384 HOOK_TDI_EXIT(TRUE);
385 }
386
387
388 if (Callback.Routine)
389 {
390 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("TDI Callback.Routine\n"));
391
392 //XXX IoCopyCurrentIrpStackLocationToNext()
393 IoSetCompletionRoutine(pIrp, Callback.Routine, Callback.Context, TRUE, TRUE, TRUE);
394 }
395 else
396 {
397 // Set up a completion routine to handle the bubbling of the "pending" mark of an IRP
398// IoSetCompletionRoutine(pIrp, GenericCompletion, NULL, TRUE, TRUE, TRUE);
399
400 IoSkipCurrentIrpStackLocation(pIrp);
401 }
402
403
404 if (DeviceType == NET_DEVICE_TYPE_TCP)
405 {
406 *status = IoCallDriver(pTcpDeviceOriginal, pIrp);
407 }
408 else if (DeviceType == NET_DEVICE_TYPE_UDP)
409 {
410 *status = IoCallDriver(pUdpDeviceOriginal, pIrp);
411 }
412 else if (DeviceType == NET_DEVICE_TYPE_IP)
413 {
414 *status = IoCallDriver(pIpDeviceOriginal, pIrp);
415 }
416 else
417 {
418 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("TDIDispatch: Unknown device type\n"));
419 }
420
421
422 HOOK_TDI_EXIT(TRUE);
423}
424
425
426
427NTSTATUS
428TDICreateAddressCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp, IN PVOID Context)
429{
430 return STATUS_SUCCESS;
431}
432
433
434
435NTSTATUS
436TDICreate(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpStack, OUT PTDI_CALLBACK pCompletion)
437{
438 FILE_FULL_EA_INFORMATION *ea = (FILE_FULL_EA_INFORMATION *) pIrp->AssociatedIrp.SystemBuffer;
439
440
441 HOOK_ROUTINE_ENTER();
442
443
444 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("TDICreate(%x %x %x)\n", pIrp, pIrpStack, ea));
445
446
447 /*
448 * From DDK (TdiDispatchCreate):
449 *
450 * Irp->AssociatedIrp.SystemBuffer
451 *
452 * Pointer to a FILE_FULL_EA_INFORMATION-structured buffer if the file object represents an address or a
453 * connection endpoint to be opened.
454 * For an address, the EaName member is set to the system-defined constant TdiTransportAddress and the EA value
455 * following the EaName array is of type TRANSPORT_ADDRESS, set up by the client to specify the address to be
456 * opened. For some transports, this value can be a symbolic netBIOS or DNS name to be translated by the transport.
457 *
458 * For a connection endpoint, the EaName member is set to the system-defined constant TdiConnectionContext and
459 * the EA value following the EaName array is a client-supplied handle, opaque to the transport driver. The
460 * transport must save this handle and subsequently pass it back to the client's registered event handlers for
461 * this connection.
462 *
463 * If the given file object represents a control channel, this member is NULL.
464 */
465
466 if (ea == NULL)
467 {
468 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("TDICreate: Control channel\n"));
469 HOOK_ROUTINE_EXIT(STATUS_SUCCESS);
470 }
471
472
473 if (! MmIsAddressValid(ea) || ea->EaName == NULL || ! MmIsAddressValid(ea->EaName))
474 {
475 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("TDICreate: MmIsAddressValid() failed\n"));
476 HOOK_ROUTINE_EXIT(STATUS_SUCCESS);
477 }
478
479
480 if (ea->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH &&
481 memcmp(ea->EaName, TdiConnectionContext, TDI_CONNECTION_CONTEXT_LENGTH) == 0)
482 {
483 CONNECTION_CONTEXT conn_ctx = *(CONNECTION_CONTEXT *) (ea->EaName + ea->EaNameLength + 1);
484
485 if (conn_ctx)
486 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("TDI Connection object 0x%x %x\n", conn_ctx, * (PULONG) conn_ctx));
487
488 HOOK_ROUTINE_EXIT(STATUS_SUCCESS);
489 }
490
491
492 // NOTE: for RawIp you can extract protocol number from irps->FileObject->FileName
493
494 if (ea->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH &&
495 memcmp(ea->EaName, TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH) == 0)
496 {
497 PTRANSPORT_ADDRESS pTransportAddress;
498 PTA_ADDRESS pAddress;
499 PIRP QueryIrp;
500 int i;
501
502
503 pTransportAddress = (PTRANSPORT_ADDRESS) (ea->EaName + ea->EaNameLength + 1);
504 pAddress = pTransportAddress->Address;
505
506 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("TDICreate: TDI Address object. Num %d\n", pTransportAddress->TAAddressCount));
507
508
509 for (i = 0; i < pTransportAddress->TAAddressCount; i++)
510 {
511 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("TDICreate: TDI Address %d: %x %x\n", i, pAddress->AddressLength, pAddress->AddressType));
512
513
514 if (pAddress->AddressType == TDI_ADDRESS_TYPE_IP)
515 {
516 PTDI_ADDRESS_IP ip = (PTDI_ADDRESS_IP) &pAddress->Address;
517 CHAR NETWORKNAME[MAX_PATH];
518 PCHAR FunctionName = "TDICreate";
519
520
521 if (ip->sin_port != 0)
522 {
523 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("%d TDICreate: Bind IP %x:%u (%s)\n", (ULONG) PsGetCurrentProcessId(), ntohl(ip->in_addr), ntohs(ip->sin_port), inet_ntoa2(ip->in_addr)));
524
525 itoa( ntohs(ip->sin_port), NETWORKNAME, 10 );
526 //inet_ntoa(ip->in_addr, NETWORKNAME);
527
528 if (LearningMode == FALSE)
529 {
530 POLICY_CHECK_OPTYPE_NAME(NETWORK, OP_BIND);
531 }
532 else
533 {
534 // learning mode
535 AddRule(RULE_NETWORK, NETWORKNAME, OP_BIND);
536 }
537 }
538 else
539 {
540 LOG(LOG_SS_NETWORK, LOG_PRIORITY_VERBOSE, ("%d TDICreate: IP & port are both zero\n", (ULONG) PsGetCurrentProcessId()));
541 }
542 }
543 else
544 {
545 //XXX fail if only IP network addresses are allowed.
546 }
547
548 pAddress += 1;
549 }
550
551 //XXX reread WDM ch 5.3 "COmpleting I/O requests"
552/*
553 QueryIrp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION, pDeviceObject,
554 pIrpStack->FileObject, NULL, NULL);
555 if (QueryIrp == NULL)
556 {
557 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("TDICreate: QueryIrp is NULL\n"));
558 return FALSE;
559 }
560
561 pCompletion->Routine = TDICreateAddressCompletion;
562 pCompletion->Context = QueryIrp;
563*/
564 }
565
566
567 HOOK_ROUTINE_EXIT(STATUS_SUCCESS);
568}
569
570
571
572/*
573 * InstallNetworkHooks()
574 *
575 * Description:
576 * .
577 *
578 * NOTE: Called once during driver initialization (DriverEntry()).
579 * There is no need to cleanup in case a failure since RemoveNetworkHooks() will be called later.
580 *
581 * Parameters:
582 * pDriverObject - pointer to a driver object that represents this driver.
583 *
584 * Returns:
585 * STATUS_SUCCESS to indicate success or an NTSTATUS error code if failed.
586 */
587
588NTSTATUS
589InstallNetworkHooks(PDRIVER_OBJECT pDriverObject)
590{
591 UNICODE_STRING Name;
592 NTSTATUS status;
593
594
595 status = IoCreateDevice(pDriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, TRUE, &pTcpDevice);
596 if (! NT_SUCCESS(status))
597 {
598 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("InstallNetworkHooks: IoCreateDevice(tcp) failed\n"));
599 return status;
600 }
601
602
603 status = IoCreateDevice(pDriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, TRUE, &pUdpDevice);
604 if (! NT_SUCCESS(status))
605 {
606 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("InstallNetworkHooks: IoCreateDevice(udp) failed\n"));
607 return status;
608 }
609
610
611 status = IoCreateDevice(pDriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, TRUE, &pIpDevice);
612 if (! NT_SUCCESS(status))
613 {
614 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("InstallNetworkHooks: IoCreateDevice(udp) failed\n"));
615 return status;
616 }
617
618
619 RtlInitUnicodeString(&Name, L"\\Device\\Tcp");
620
621 status = IoAttachDevice(pTcpDevice, &Name, &pTcpDeviceOriginal);
622 if (! NT_SUCCESS(status))
623 {
624 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("InstallNetworkHooks: IoAttachDevice(\\Device\\Tcp) failed\n"));
625 return status;
626 }
627
628
629 RtlInitUnicodeString(&Name, L"\\Device\\Udp");
630
631 status = IoAttachDevice(pUdpDevice, &Name, &pUdpDeviceOriginal);
632 if (! NT_SUCCESS(status))
633 {
634 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("InstallNetworkHooks: IoAttachDevice(\\Device\\Udp) failed\n"));
635 return status;
636 }
637
638
639 RtlInitUnicodeString(&Name, L"\\Device\\Ip");
640
641 status = IoAttachDevice(pIpDevice, &Name, &pIpDeviceOriginal);
642 if (! NT_SUCCESS(status))
643 {
644 LOG(LOG_SS_NETWORK, LOG_PRIORITY_DEBUG, ("InstallNetworkHooks: IoAttachDevice(\\Device\\Ip) failed\n"));
645 return status;
646 }
647
648
649 pTcpDevice->StackSize = pTcpDeviceOriginal->StackSize + 1;
650 // XXX Flags &= ~DO_DEVICE_INITIALIZING;
651 pTcpDevice->Flags |= pTcpDeviceOriginal->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH) & ~DO_DEVICE_INITIALIZING;
652 pTcpDevice->DeviceType = pTcpDeviceOriginal->DeviceType;
653 pTcpDevice->Characteristics = pTcpDeviceOriginal->Characteristics;
654
655
656 pUdpDevice->StackSize = pUdpDeviceOriginal->StackSize + 1;
657 pUdpDevice->Flags |= pUdpDeviceOriginal->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH) & ~DO_DEVICE_INITIALIZING;
658 pUdpDevice->DeviceType = pUdpDeviceOriginal->DeviceType;
659 pUdpDevice->Characteristics = pUdpDeviceOriginal->Characteristics;
660
661
662 pIpDevice->StackSize = pIpDeviceOriginal->StackSize + 1;
663 pIpDevice->Flags |= pIpDeviceOriginal->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH) & ~DO_DEVICE_INITIALIZING;
664 pIpDevice->DeviceType = pIpDeviceOriginal->DeviceType;
665 pIpDevice->Characteristics = pIpDeviceOriginal->Characteristics;
666
667
668 return STATUS_SUCCESS;
669}
670
671
672
673/*
674 * RemoveNetworkHooks()
675 *
676 * Description:
677 * Detach from all network devices.
678 *
679 * Parameters:
680 * pDriverObject - pointer to a driver object that represents this driver.
681 *
682 * Returns:
683 * Nothing.
684 */
685
686void
687RemoveNetworkHooks(PDRIVER_OBJECT pDriverObject)
688{
689// int i;
690
691 //XXX is this necessary? we detach so we should not receive any network IRPs
692// if (pDriverObject && pTcpDevice && pTcpDeviceOriginal)
693// for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
694// pDriverObject->MajorFunction[i] = pTcpDeviceOriginal->DriverObject->MajorFunction[i];
695
696
697 if (pTcpDeviceOriginal != NULL)
698 IoDetachDevice(pTcpDeviceOriginal);
699
700 if (pUdpDeviceOriginal != NULL)
701 IoDetachDevice(pUdpDeviceOriginal);
702
703 if (pIpDeviceOriginal != NULL)
704 IoDetachDevice(pIpDeviceOriginal);
705
706
707 if (pTcpDevice != NULL)
708 IoDeleteDevice(pTcpDevice);
709
710 if (pUdpDevice != NULL)
711 IoDeleteDevice(pUdpDevice);
712
713 if (pIpDevice != NULL)
714 IoDeleteDevice(pIpDevice);
715}