21ac96166e8727b1e55d7712100263ac1a6bb592
[reactos.git] / reactos / drivers / network / tcpip / tcpip / iinfo.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/iinfo.c
5 * PURPOSE: Per-interface information.
6 * PROGRAMMERS: Art Yerkes
7 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10
11 #include "precomp.h"
12
13 TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID,
14 PIP_INTERFACE Interface,
15 PNDIS_BUFFER Buffer,
16 PUINT BufferSize) {
17 TDI_STATUS Status = TDI_INVALID_REQUEST;
18 PIFENTRY OutData;
19 PLAN_ADAPTER IF = (PLAN_ADAPTER)Interface->Context;
20 PCHAR IFDescr;
21 ULONG Size;
22 UINT DescrLenMax = MAX_IFDESCR_LEN - 1;
23 NDIS_STATUS NdisStatus;
24
25 TI_DbgPrint(DEBUG_INFO,
26 ("Getting IFEntry MIB (IF %08x LA %08x) (%04x:%d)\n",
27 Interface, IF, ID->tei_entity, ID->tei_instance));
28
29 OutData =
30 (PIFENTRY)exAllocatePool( NonPagedPool,
31 sizeof(IFENTRY) + MAX_IFDESCR_LEN );
32
33 if( !OutData ) return TDI_NO_RESOURCES; /* Out of memory */
34
35 RtlZeroMemory( OutData, sizeof(IFENTRY) + MAX_IFDESCR_LEN );
36
37 OutData->Index = Interface->Index;
38 /* viz: tcpip keeps those indices */
39 OutData->Type = Interface ==
40 Loopback ? MIB_IF_TYPE_LOOPBACK : MIB_IF_TYPE_ETHERNET;
41 OutData->Mtu = Interface->MTU;
42 TI_DbgPrint(DEBUG_INFO,
43 ("Getting interface speed\n"));
44 OutData->PhysAddrLen = Interface->AddressLength;
45 OutData->AdminStatus = MIB_IF_ADMIN_STATUS_UP;
46 /* NDIS_HARDWARE_STATUS -> ROUTER_CONNECTION_STATE */
47 Status = GetInterfaceConnectionStatus( Interface, &OutData->OperStatus );
48
49 /* Not sure what to do here, but not ready seems a safe bet on failure */
50 if( !NT_SUCCESS(Status) )
51 OutData->OperStatus = NdisHardwareStatusNotReady;
52
53 IFDescr = (PCHAR)&OutData[1];
54
55 if( IF ) {
56 GetInterfaceSpeed( Interface, (PUINT)&OutData->Speed );
57 TI_DbgPrint(DEBUG_INFO,
58 ("IF Speed = %d * 100bps\n", OutData->Speed));
59 memcpy(OutData->PhysAddr,Interface->Address,Interface->AddressLength);
60 TI_DbgPrint(DEBUG_INFO, ("Got HWAddr\n"));
61
62 memcpy(&OutData->InOctets, &Interface->Stats, sizeof(SEND_RECV_STATS));
63
64 NdisStatus = NDISCall(IF,
65 NdisRequestQueryInformation,
66 OID_GEN_XMIT_ERROR,
67 &OutData->OutErrors,
68 sizeof(ULONG));
69 if (NdisStatus != NDIS_STATUS_SUCCESS)
70 OutData->OutErrors = 0;
71
72 TI_DbgPrint(DEBUG_INFO, ("OutErrors = %d\n", OutData->OutErrors));
73
74 NdisStatus = NDISCall(IF,
75 NdisRequestQueryInformation,
76 OID_GEN_RCV_ERROR,
77 &OutData->InErrors,
78 sizeof(ULONG));
79 if (NdisStatus != NDIS_STATUS_SUCCESS)
80 OutData->InErrors = 0;
81
82 TI_DbgPrint(DEBUG_INFO, ("InErrors = %d\n", OutData->InErrors));
83 }
84
85 GetInterfaceName( Interface, IFDescr, MAX_IFDESCR_LEN - 1 );
86 DescrLenMax = strlen( IFDescr ) + 1;
87
88 TI_DbgPrint(DEBUG_INFO, ("Copied in name %s\n", IFDescr));
89 OutData->DescrLen = DescrLenMax;
90 IFDescr += DescrLenMax;
91 Size = IFDescr - (PCHAR)OutData + 1;
92
93 TI_DbgPrint(DEBUG_INFO, ("Finished IFEntry MIB (%04x:%d) size %d\n",
94 ID->tei_entity, ID->tei_instance, Size));
95
96 Status = InfoCopyOut( (PCHAR)OutData, Size, Buffer, BufferSize );
97 exFreePool( OutData );
98
99 TI_DbgPrint(DEBUG_INFO,("Returning %x\n", Status));
100
101 return Status;
102 }
103
104 TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID *ID,
105 PIP_INTERFACE Interface,
106 PNDIS_BUFFER Buffer,
107 PUINT BufferSize) {
108 NTSTATUS Status;
109 ULONG NumNeighbors = NBCopyNeighbors( Interface, NULL );
110 ULONG MemSize = NumNeighbors * sizeof(IPARP_ENTRY);
111 PIPARP_ENTRY ArpEntries =
112 exAllocatePoolWithTag
113 ( NonPagedPool, MemSize, FOURCC('A','R','P','t') );
114
115 if( !ArpEntries ) return STATUS_NO_MEMORY;
116 NBCopyNeighbors( Interface, ArpEntries );
117
118 Status = InfoCopyOut( (PVOID)ArpEntries, MemSize, Buffer, BufferSize );
119
120 exFreePool( ArpEntries );
121
122 return Status;
123 }
124
125 TDI_STATUS InfoTdiQueryGetArpCapability(TDIEntityID *ID,
126 PIP_INTERFACE Interface,
127 PNDIS_BUFFER Buffer,
128 PUINT BufferSize) {
129 NTSTATUS Status;
130 ULONG Capability = 0x280;
131
132 TI_DbgPrint(MID_TRACE,("Copying out %d bytes (AT_ENTITY capability)\n",
133 sizeof(Capability)));
134 Status = InfoCopyOut
135 ( (PVOID)&Capability, sizeof(Capability), Buffer, BufferSize );
136
137 return Status;
138 }
139
140 TDI_STATUS InfoInterfaceTdiQueryEx( UINT InfoClass,
141 UINT InfoType,
142 UINT InfoId,
143 PVOID Context,
144 TDIEntityID *id,
145 PNDIS_BUFFER Buffer,
146 PUINT BufferSize ) {
147 if( InfoClass == INFO_CLASS_GENERIC &&
148 InfoType == INFO_TYPE_PROVIDER &&
149 InfoId == ENTITY_TYPE_ID &&
150 id->tei_entity == AT_ENTITY ) {
151 return InfoTdiQueryGetArpCapability( id, Context, Buffer, BufferSize );
152 } else if( InfoClass == INFO_CLASS_PROTOCOL &&
153 InfoType == INFO_TYPE_PROVIDER &&
154 InfoId == IF_MIB_STATS_ID ) {
155 return InfoTdiQueryGetInterfaceMIB( id, Context, Buffer, BufferSize );
156 } else if( InfoClass == INFO_CLASS_GENERIC &&
157 InfoType == INFO_TYPE_PROVIDER &&
158 InfoId == ENTITY_TYPE_ID ) {
159 ULONG Temp = IF_MIB;
160 return InfoCopyOut( (PCHAR)&Temp, sizeof(Temp), Buffer, BufferSize );
161 } else if( InfoClass == INFO_CLASS_PROTOCOL &&
162 InfoType == INFO_TYPE_PROVIDER &&
163 InfoId == IP_MIB_ARPTABLE_ENTRY_ID ) {
164 return InfoTdiQueryGetArptableMIB( id, Context, Buffer, BufferSize );
165 } else
166 return TDI_INVALID_REQUEST;
167 }
168
169 TDI_STATUS InfoInterfaceTdiSetEx( UINT InfoClass,
170 UINT InfoType,
171 UINT InfoId,
172 PVOID Context,
173 TDIEntityID *id,
174 PCHAR Buffer,
175 UINT BufferSize ) {
176 TI_DbgPrint(DEBUG_INFO, ("Got Request: Class %x Type %x Id %x, EntityID %x:%x\n",
177 InfoClass, InfoId, id->tei_entity, id->tei_instance));
178 return TDI_INVALID_REQUEST;
179 }