xbox-kernel/private/ntos/xnet/ip/ipinit.c
2020-09-30 17:17:25 +02:00

206 lines
4.0 KiB
C

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
ipinit.c
Abstract:
IP module initialization and cleanup related functions
Revision History:
05/24/2000 davidx
Created it.
--*/
#include "precomp.h"
//
// Global interface table
//
IfInfo* Interfaces[IFINDEX_MAX];
VOID
IpTimerProc()
/*++
Routine Description:
IP timer routine - called once a second
Arguments:
dpc, context, param1, param2 - DPC function parameters
Return Value:
NONE
--*/
{
IfInfo* ifp;
// Call interface timer routines
LOOP_THRU_INTERFACE_LIST(ifp)
// NOTE: This is a hack to ensure we don't call the Ethernet interface's
// timer function twice when we are running under the debug monitor.
if (XnetInsideDbgmon() &&
ifp->refcount > 1 &&
IfRunning(ifp))
continue;
if (ifp->Timer) ifp->Timer(ifp);
if (ifp->mcastData) {
IgmpTimerProc(ifp);
}
if (IfDhcpEnabled(ifp)) {
DhcpTimerProc(ifp);
}
END_INTERFACE_LIST_LOOP()
// Datagram reassembly timer routine
IpReassemblyTimerProc();
}
//
// Interface initialization function
//
typedef NTSTATUS (*IfInitProc)(IfInfo**);
static const IfInitProc IfInitProcTable[IFINDEX_MAX] = {
LoopbackInitialize, // loopback interface
EnetInitialize, // Ethernet interface
NULL // dial-up interface
};
NTSTATUS
IpInitialize()
/*++
Routine Description:
Initialize the IP module
Arguments:
NONE
Return Value:
Status code
--*/
{
NTSTATUS status;
UINT ifindex;
status = IpInitRouteTable();
if (!NT_SUCCESS(status)) goto failed;
for (ifindex=0; ifindex < IFINDEX_MAX; ifindex++) {
IfInitProc initProc = IfInitProcTable[ifindex];
IfInfo* ifp;
if (!initProc) continue;
status = initProc(&ifp);
if (!NT_SUCCESS(status)) goto failed;
ASSERT(ifp->hwaddrlen <= MAXHWADDRLEN);
Interfaces[ifindex] = ifp;
// Adjust the pseudo-random number generator seed
// with the Ethernet hardware ID
if (ifp->iftype == IFTYPE_ETHERNET) {
ULONG seed = 0;
WORD addrbyte;
for (addrbyte=0; addrbyte < ifp->hwaddrlen; addrbyte++) {
seed = (seed << 8) ^ ifp->hwaddr[addrbyte];
}
XnetRandSeed = (XnetRandSeed ^ seed) & 0x7fffffff;
}
if (IfBcastEnabled(ifp)) {
status = IpSetBroadcastInterface(ifp);
if (!NT_SUCCESS(status)) goto failed;
}
if (IfMcastEnabled(ifp)) {
status = IfInitMcastGroup(ifp);
if (!NT_SUCCESS(status)) goto failed;
}
if (IfDhcpEnabled(ifp)) {
status = DhcpInitialize(ifp);
if (!NT_SUCCESS(status)) goto failed;
}
}
IpNextDgramId = (WORD) XnetRand();
return NETERR_OK;
failed:
WARNING_("IpInitialize failed: 0x%x", status);
return status;
}
VOID
IpCleanup()
/*++
Routine Description:
Cleanup the IP module
Arguments:
NONE
Return Value:
NONE
--*/
{
IfInfo* ifp;
RUNS_AT_DISPATCH_LEVEL
// Cleanup DHCP info
LOOP_THRU_INTERFACE_LIST(ifp)
if (IfDhcpEnabled(ifp)) {
DhcpCleanup(ifp);
}
END_INTERFACE_LIST_LOOP()
IpCleanupReassemblyPkts(NULL);
IpCleanupRouteTable();
// Delete the interfaces
LOOP_THRU_INTERFACE_LIST(ifp)
Interfaces[_ifindex] = NULL;
// NOTE: We shouldn't free per-interface multicast data
// if the interface is shared by the debug monitor stack.
if (ifp->refcount <= 1) {
SysFree(ifp->mcastData);
ifp->mcastData = NULL;
}
ifp->Delete(ifp);
END_INTERFACE_LIST_LOOP()
ZeroMem(Interfaces, sizeof(Interfaces));
}