- Don't add the media-specific header until right before transmission
[reactos.git] / reactos / 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 LoopTransmit(
16 PVOID Context,
17 PNDIS_PACKET NdisPacket,
18 UINT Offset,
19 PVOID LinkAddress,
20 USHORT Type)
21 /*
22 * FUNCTION: Transmits a packet
23 * ARGUMENTS:
24 * Context = Pointer to context information (NULL)
25 * NdisPacket = Pointer to NDIS packet to send
26 * Offset = Offset in packet where packet data starts
27 * LinkAddress = Pointer to link address
28 * Type = LAN protocol type (unused)
29 */
30 {
31 PCHAR PacketBuffer;
32 UINT PacketLength;
33 PNDIS_PACKET XmitPacket;
34 NDIS_STATUS NdisStatus;
35 IP_PACKET IPPacket;
36 PNDIS_BUFFER NdisBuffer;
37
38 ASSERT_KM_POINTER(NdisPacket);
39 ASSERT_KM_POINTER(PC(NdisPacket));
40 ASSERT_KM_POINTER(PC(NdisPacket)->DLComplete);
41
42 TI_DbgPrint(MAX_TRACE, ("Called (NdisPacket = %x)\n", NdisPacket));
43
44 GetDataPtr( NdisPacket, 0, &PacketBuffer, &PacketLength );
45
46 NdisStatus = AllocatePacketWithBuffer
47 ( &XmitPacket, PacketBuffer, PacketLength );
48
49 (PC(NdisPacket)->DLComplete)
50 ( PC(NdisPacket)->Context, NdisPacket, NdisStatus );
51
52 if( NT_SUCCESS(NdisStatus) ) {
53 IPInitializePacket(&IPPacket, 0);
54
55 IPPacket.NdisPacket = XmitPacket;
56
57 NdisGetFirstBufferFromPacket(XmitPacket,
58 &NdisBuffer,
59 &IPPacket.Header,
60 &IPPacket.ContigSize,
61 &IPPacket.TotalSize);
62
63 IPReceive(Loopback, &IPPacket);
64
65 FreeNdisPacket(XmitPacket);
66 }
67
68 TI_DbgPrint(MAX_TRACE, ("Done\n"));
69 }
70
71 NDIS_STATUS LoopRegisterAdapter(
72 PNDIS_STRING AdapterName,
73 PLAN_ADAPTER *Adapter)
74 /*
75 * FUNCTION: Registers loopback adapter with the network layer
76 * ARGUMENTS:
77 * AdapterName = Unused
78 * Adapter = Unused
79 * RETURNS:
80 * Status of operation
81 */
82 {
83 LLIP_BIND_INFO BindInfo;
84
85 TI_DbgPrint(MID_TRACE, ("Called.\n"));
86
87 /* Bind the adapter to network (IP) layer */
88 BindInfo.Context = NULL;
89 BindInfo.HeaderSize = 0;
90 BindInfo.MinFrameSize = 0;
91 BindInfo.MTU = 16384;
92 BindInfo.Address = NULL;
93 BindInfo.AddressLength = 0;
94 BindInfo.Transmit = LoopTransmit;
95
96 Loopback = IPCreateInterface(&BindInfo);
97 if (!Loopback) return NDIS_STATUS_RESOURCES;
98
99 Loopback->Name.Buffer = L"Loopback";
100 Loopback->Name.MaximumLength = Loopback->Name.Length =
101 wcslen(Loopback->Name.Buffer) * sizeof(WCHAR);
102
103 AddrInitIPv4(&Loopback->Unicast, LOOPBACK_ADDRESS_IPv4);
104 AddrInitIPv4(&Loopback->Netmask, LOOPBACK_ADDRMASK_IPv4);
105 AddrInitIPv4(&Loopback->Broadcast, LOOPBACK_BCASTADDR_IPv4);
106
107 IPRegisterInterface(Loopback);
108 IPAddInterfaceRoute(Loopback);
109
110 TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
111
112 return NDIS_STATUS_SUCCESS;
113 }
114
115
116 NDIS_STATUS LoopUnregisterAdapter(
117 PLAN_ADAPTER Adapter)
118 /*
119 * FUNCTION: Unregisters loopback adapter with the network layer
120 * ARGUMENTS:
121 * Adapter = Unused
122 * RETURNS:
123 * Status of operation
124 * NOTES:
125 * Does not care wether we have registered loopback adapter
126 */
127 {
128 TI_DbgPrint(MID_TRACE, ("Called.\n"));
129
130 if (Loopback != NULL)
131 {
132 IPUnregisterInterface(Loopback);
133 IPDestroyInterface(Loopback);
134 Loopback = NULL;
135 }
136
137 TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
138
139 return NDIS_STATUS_SUCCESS;
140 }