Synchronize with trunk r58457.
[reactos.git] / 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;
20 PCHAR IFDescr;
21 ULONG Size;
22 UINT DescrLenMax = MAX_IFDESCR_LEN - 1;
23 NDIS_STATUS NdisStatus;
24
25 if (!Interface)
26 return TDI_INVALID_PARAMETER;
27
28 IF = (PLAN_ADAPTER)Interface->Context;
29
30 TI_DbgPrint(DEBUG_INFO,
31 ("Getting IFEntry MIB (IF %08x LA %08x) (%04x:%d)\n",
32 Interface, IF, ID.tei_entity, ID.tei_instance));
33
34 OutData =
35 (PIFENTRY)ExAllocatePool( NonPagedPool,
36 sizeof(IFENTRY) + MAX_IFDESCR_LEN );
37
38 if( !OutData ) return TDI_NO_RESOURCES; /* Out of memory */
39
40 RtlZeroMemory( OutData, sizeof(IFENTRY) + MAX_IFDESCR_LEN );
41
42 OutData->Index = Interface->Index;
43 /* viz: tcpip keeps those indices */
44 OutData->Type = Interface ==
45 Loopback ? MIB_IF_TYPE_LOOPBACK : MIB_IF_TYPE_ETHERNET;
46 OutData->Mtu = Interface->MTU;
47 TI_DbgPrint(DEBUG_INFO,
48 ("Getting interface speed\n"));
49 OutData->PhysAddrLen = Interface->AddressLength;
50 OutData->AdminStatus = MIB_IF_ADMIN_STATUS_UP;
51 /* NDIS_HARDWARE_STATUS -> ROUTER_CONNECTION_STATE */
52 Status = GetInterfaceConnectionStatus( Interface, &OutData->OperStatus );
53
54 /* Not sure what to do here, but not ready seems a safe bet on failure */
55 if( !NT_SUCCESS(Status) )
56 OutData->OperStatus = NdisHardwareStatusNotReady;
57
58 IFDescr = (PCHAR)&OutData[1];
59
60 if( IF ) {
61 GetInterfaceSpeed( Interface, (PUINT)&OutData->Speed );
62 TI_DbgPrint(DEBUG_INFO,
63 ("IF Speed = %d * 100bps\n", OutData->Speed));
64 memcpy(OutData->PhysAddr,Interface->Address,Interface->AddressLength);
65 TI_DbgPrint(DEBUG_INFO, ("Got HWAddr\n"));
66
67 memcpy(&OutData->InOctets, &Interface->Stats, sizeof(SEND_RECV_STATS));
68
69 NdisStatus = NDISCall(IF,
70 NdisRequestQueryInformation,
71 OID_GEN_XMIT_ERROR,
72 &OutData->OutErrors,
73 sizeof(ULONG));
74 if (NdisStatus != NDIS_STATUS_SUCCESS)
75 OutData->OutErrors = 0;
76
77 TI_DbgPrint(DEBUG_INFO, ("OutErrors = %d\n", OutData->OutErrors));
78
79 NdisStatus = NDISCall(IF,
80 NdisRequestQueryInformation,
81 OID_GEN_RCV_ERROR,
82 &OutData->InErrors,
83 sizeof(ULONG));
84 if (NdisStatus != NDIS_STATUS_SUCCESS)
85 OutData->InErrors = 0;
86
87 TI_DbgPrint(DEBUG_INFO, ("InErrors = %d\n", OutData->InErrors));
88 }
89
90 GetInterfaceName( Interface, IFDescr, MAX_IFDESCR_LEN - 1 );
91 DescrLenMax = strlen( IFDescr ) + 1;
92
93 TI_DbgPrint(DEBUG_INFO, ("Copied in name %s\n", IFDescr));
94 OutData->DescrLen = DescrLenMax;
95 IFDescr += DescrLenMax;
96 Size = IFDescr - (PCHAR)OutData + 1;
97
98 TI_DbgPrint(DEBUG_INFO, ("Finished IFEntry MIB (%04x:%d) size %d\n",
99 ID.tei_entity, ID.tei_instance, Size));
100
101 Status = InfoCopyOut( (PCHAR)OutData, Size, Buffer, BufferSize );
102 ExFreePool( OutData );
103
104 TI_DbgPrint(DEBUG_INFO,("Returning %x\n", Status));
105
106 return Status;
107 }
108
109 TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID ID,
110 PIP_INTERFACE Interface,
111 PNDIS_BUFFER Buffer,
112 PUINT BufferSize) {
113 NTSTATUS Status;
114 ULONG NumNeighbors = NBCopyNeighbors( Interface, NULL );
115 ULONG MemSize = NumNeighbors * sizeof(IPARP_ENTRY);
116 PIPARP_ENTRY ArpEntries;
117
118 if (MemSize != 0)
119 {
120 ArpEntries = ExAllocatePool( NonPagedPool, MemSize );
121 if( !ArpEntries ) return STATUS_NO_MEMORY;
122
123 NBCopyNeighbors( Interface, ArpEntries );
124
125 Status = InfoCopyOut( (PVOID)ArpEntries, MemSize, Buffer, BufferSize );
126
127 ExFreePool( ArpEntries );
128 }
129 else
130 {
131 Status = InfoCopyOut(NULL, 0, NULL, BufferSize);
132 }
133
134 return Status;
135 }
136
137 TDI_STATUS InfoTdiSetArptableMIB(PIP_INTERFACE IF, PVOID Buffer, UINT BufferSize)
138 {
139 PIPARP_ENTRY ArpEntry = Buffer;
140 IP_ADDRESS Address;
141 PNEIGHBOR_CACHE_ENTRY NCE;
142
143 if (!Buffer || BufferSize < sizeof(IPARP_ENTRY))
144 return TDI_INVALID_PARAMETER;
145
146 AddrInitIPv4(&Address, ArpEntry->LogAddr);
147
148 if ((NCE = NBLocateNeighbor(&Address)))
149 NBRemoveNeighbor(NCE);
150
151 if (NBAddNeighbor(IF,
152 &Address,
153 ArpEntry->PhysAddr,
154 ArpEntry->AddrSize,
155 NUD_PERMANENT,
156 0))
157 return TDI_SUCCESS;
158 else
159 return TDI_INVALID_PARAMETER;
160 }
161
162 VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface ) {
163 AddEntity(IF_ENTITY, Interface, IF_MIB);
164
165 AddEntity(AT_ENTITY, Interface,
166 (Interface != Loopback) ? AT_ARP : AT_NULL);
167
168 /* FIXME: This is probably wrong */
169 AddEntity(CL_NL_ENTITY, Interface, CL_NL_IP);
170 }
171
172 VOID RemoveTDIInterfaceEntity( PIP_INTERFACE Interface ) {
173 /* This removes all of them */
174 RemoveEntityByContext(Interface);
175 }
176