xref: /reactos/drivers/network/tcpip/tcpip/iinfo.c (revision 34593d93)
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 
InfoTdiQueryGetInterfaceMIB(TDIEntityID ID,PIP_INTERFACE Interface,PNDIS_BUFFER Buffer,PUINT BufferSize)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 
InfoTdiQueryGetArptableMIB(TDIEntityID ID,PIP_INTERFACE Interface,PNDIS_BUFFER Buffer,PUINT BufferSize)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 
InfoTdiSetArptableMIB(PIP_INTERFACE IF,PVOID Buffer,UINT BufferSize)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 
InsertTDIInterfaceEntity(PIP_INTERFACE Interface)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 
RemoveTDIInterfaceEntity(PIP_INTERFACE Interface)168 VOID RemoveTDIInterfaceEntity( PIP_INTERFACE Interface ) {
169     /* This removes all of them */
170     RemoveEntityByContext(Interface);
171 }
172