e44cc69d3d7ac090a1da232f019910b248a963fe
[reactos.git] / sdk / lib / drivers / ip / network / loopback.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: datalink/loopback.c
5 * PURPOSE: Loopback adapter
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10
11 #include "precomp.h"
12
13 PIP_INTERFACE Loopback = NULL;
14
15 VOID LoopPassiveWorker(
16 PVOID Context)
17 {
18 PIP_PACKET IPPacket = Context;
19
20 /* IPReceive() takes care of the NDIS packet */
21 IPReceive(Loopback, IPPacket);
22
23 ExFreePool(IPPacket);
24 }
25
26 VOID LoopTransmit(
27 PVOID Context,
28 PNDIS_PACKET NdisPacket,
29 UINT Offset,
30 PVOID LinkAddress,
31 USHORT Type)
32 /*
33 * FUNCTION: Transmits a packet
34 * ARGUMENTS:
35 * Context = Pointer to context information (NULL)
36 * NdisPacket = Pointer to NDIS packet to send
37 * Offset = Offset in packet where packet data starts
38 * LinkAddress = Pointer to link address
39 * Type = LAN protocol type (unused)
40 */
41 {
42 PCHAR PacketBuffer;
43 UINT PacketLength;
44 PNDIS_PACKET XmitPacket;
45 NDIS_STATUS NdisStatus;
46 PIP_PACKET IPPacket;
47
48 ASSERT_KM_POINTER(NdisPacket);
49 ASSERT_KM_POINTER(PC(NdisPacket));
50 ASSERT_KM_POINTER(PC(NdisPacket)->DLComplete);
51
52 TI_DbgPrint(MAX_TRACE, ("Called (NdisPacket = %x)\n", NdisPacket));
53
54 GetDataPtr( NdisPacket, 0, &PacketBuffer, &PacketLength );
55
56 NdisStatus = AllocatePacketWithBuffer
57 ( &XmitPacket, PacketBuffer, PacketLength );
58
59 if( NT_SUCCESS(NdisStatus) ) {
60 IPPacket = ExAllocatePool(NonPagedPool, sizeof(IP_PACKET));
61 if (IPPacket)
62 {
63 IPInitializePacket(IPPacket, 0);
64
65 IPPacket->NdisPacket = XmitPacket;
66
67 GetDataPtr(IPPacket->NdisPacket,
68 0,
69 (PCHAR*)&IPPacket->Header,
70 &IPPacket->TotalSize);
71
72 IPPacket->MappedHeader = TRUE;
73
74 if (!ChewCreate(LoopPassiveWorker, IPPacket))
75 {
76 IPPacket->Free(IPPacket);
77 ExFreePool(IPPacket);
78 NdisStatus = NDIS_STATUS_RESOURCES;
79 }
80 }
81 else
82 NdisStatus = NDIS_STATUS_RESOURCES;
83 }
84
85 (PC(NdisPacket)->DLComplete)
86 ( PC(NdisPacket)->Context, NdisPacket, NdisStatus );
87 }
88
89 NDIS_STATUS LoopRegisterAdapter(
90 PNDIS_STRING AdapterName,
91 PLAN_ADAPTER *Adapter)
92 /*
93 * FUNCTION: Registers loopback adapter with the network layer
94 * ARGUMENTS:
95 * AdapterName = Unused
96 * Adapter = Unused
97 * RETURNS:
98 * Status of operation
99 */
100 {
101 LLIP_BIND_INFO BindInfo;
102
103 TI_DbgPrint(MID_TRACE, ("Called.\n"));
104
105 /* Bind the adapter to network (IP) layer */
106 BindInfo.Context = NULL;
107 BindInfo.HeaderSize = 0;
108 BindInfo.MinFrameSize = 0;
109 BindInfo.Address = NULL;
110 BindInfo.AddressLength = 0;
111 BindInfo.Transmit = LoopTransmit;
112
113 Loopback = IPCreateInterface(&BindInfo);
114 if (!Loopback) return NDIS_STATUS_RESOURCES;
115
116 Loopback->MTU = 16384;
117
118 Loopback->Name.Buffer = L"Loopback";
119 Loopback->Name.MaximumLength = Loopback->Name.Length =
120 wcslen(Loopback->Name.Buffer) * sizeof(WCHAR);
121
122 AddrInitIPv4(&Loopback->Unicast, LOOPBACK_ADDRESS_IPv4);
123 AddrInitIPv4(&Loopback->Netmask, LOOPBACK_ADDRMASK_IPv4);
124 AddrInitIPv4(&Loopback->Broadcast, LOOPBACK_BCASTADDR_IPv4);
125
126 IPRegisterInterface(Loopback);
127
128 IPAddInterfaceRoute(Loopback);
129
130 TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
131
132 return NDIS_STATUS_SUCCESS;
133 }
134
135
136 NDIS_STATUS LoopUnregisterAdapter(
137 PLAN_ADAPTER Adapter)
138 /*
139 * FUNCTION: Unregisters loopback adapter with the network layer
140 * ARGUMENTS:
141 * Adapter = Unused
142 * RETURNS:
143 * Status of operation
144 * NOTES:
145 * Does not care wether we have registered loopback adapter
146 */
147 {
148 TI_DbgPrint(MID_TRACE, ("Called.\n"));
149
150 if (Loopback != NULL)
151 {
152 IPUnregisterInterface(Loopback);
153 IPDestroyInterface(Loopback);
154 Loopback = NULL;
155 }
156
157 TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
158
159 return NDIS_STATUS_SUCCESS;
160 }