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