Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

295 lines
6.6 KiB

/*++
Copyright (c) 1998, Microsoft Corporation
Module Name:
natarp.c
Abstract:
This module contains code for the NAT's user-mode proxy-ARP entry
management. Proxy-ARP entries are installed on dedicated interfaces
which have address-translation enabled.
Author:
Abolade Gbadegesin (aboladeg) 20-Mar-1998
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
//
// FORWARD DECLARATIONS
//
VOID
NatpCreateProxyArpCallback(
ULONG Address,
ULONG Mask,
PVOID Context
);
VOID
NatpDeleteProxyArpCallback(
ULONG Address,
ULONG Mask,
PVOID Context
);
VOID
NatpCreateProxyArpCallback(
ULONG Address,
ULONG Mask,
PVOID Context
)
/*++
Routine Description:
This routine is invoked to remove a proxy-ARP entry.
Arguments:
Address - the address to remove
Mask - the mask associated with 'Address'
Context - context-field holding the entry's interface
Return Value:
none.
--*/
{
ULONG Error;
DEFINE_MIB_BUFFER(Info, MIB_PROXYARP, Entry);
PROFILE("NatpCreateProxyArpCallback");
//
// Install an entry for the range, unless the host-portion is 1 bit wide,
// in which case the range consists only of an all-zeroes and all-ones host.
// The stack will refuse to answer ARP queries for either one,
// so adding such a range would be a waste.
//
Info->dwId = PROXY_ARP;
if (~Mask != 1) {
Entry->dwAddress = (Address & Mask);
Entry->dwMask = Mask;
Entry->dwIfIndex = ((PNAT_INTERFACE)Context)->Index;
Error =
NatSupportFunctions.MIBEntryCreate(
IPRTRMGR_PID,
MIB_INFO_SIZE(MIB_PROXYARP),
Info
);
if (Error) {
CHAR MaskString[16];
lstrcpyA(MaskString, INET_NTOA(Mask));
NhTrace(
TRACE_FLAG_NAT,
"NatpCreateProxyArpCallback: error %d adding %s/%s",
Error, INET_NTOA(Address), MaskString
);
NhInformationLog(
IP_NAT_LOG_UPDATE_ARP_FAILED,
Error,
"%I%I",
Address,
Mask
);
}
}
//
// If the mask is not all-ones, also install entries for the all-zeroes
// and all-ones host-portions of the range; otherwise IP will refuse
// to answer ARP queries for these.
//
if (~Mask) {
Entry->dwAddress = (Address & Mask);
Entry->dwMask = 0xffffffff;
Entry->dwIfIndex = ((PNAT_INTERFACE)Context)->Index;
NatSupportFunctions.MIBEntryCreate(
IPRTRMGR_PID,
MIB_INFO_SIZE(MIB_PROXYARP),
Info
);
Entry->dwAddress = (Address | ~Mask);
Entry->dwMask = 0xffffffff;
Entry->dwIfIndex = ((PNAT_INTERFACE)Context)->Index;
NatSupportFunctions.MIBEntryCreate(
IPRTRMGR_PID,
MIB_INFO_SIZE(MIB_PROXYARP),
Info
);
}
} // NatpCreateProxyArpCallback
VOID
NatpDeleteProxyArpCallback(
ULONG Address,
ULONG Mask,
PVOID Context
)
/*++
Routine Description:
This routine is invoked to remove a proxy-ARP entry.
Arguments:
Address - the address to remove
Mask - the mask associated with 'Address'
Context - context-field holding the entry's interface
Return Value:
none.
--*/
{
BYTE Buffer[FIELD_OFFSET(MIB_OPAQUE_QUERY, rgdwVarIndex) + 3*sizeof(DWORD)];
ULONG Error;
PMIB_OPAQUE_QUERY Query = (PMIB_OPAQUE_QUERY)Buffer;
PROFILE("NatpDeleteProxyArpCallback");
Query->dwVarId = PROXY_ARP;
Query->rgdwVarIndex[0] = (Address & Mask);
Query->rgdwVarIndex[1] = Mask;
Query->rgdwVarIndex[2] = ((PNAT_INTERFACE)Context)->Index;
Error =
NatSupportFunctions.MIBEntryDelete(
IPRTRMGR_PID,
MIB_INFO_SIZE(MIB_PROXYARP),
Buffer
);
if (Error) {
CHAR MaskString[16];
lstrcpyA(MaskString, INET_NTOA(Mask));
NhTrace(
TRACE_FLAG_NAT,
"NatpDeleteProxyArpCallback: error %d deleting %s/%s",
Error, INET_NTOA(Address), MaskString
);
NhInformationLog(
IP_NAT_LOG_UPDATE_ARP_FAILED,
Error,
"%I%I",
Address,
Mask
);
}
//
// If the mask is not all-ones, also remove the entries for the all-zeroes
// and all-ones host-portions of the range.
//
if (~Mask) {
Query->rgdwVarIndex[0] = (Address & Mask);
Query->rgdwVarIndex[1] = 0xffffffff;
Query->rgdwVarIndex[2] = ((PNAT_INTERFACE)Context)->Index;
NatSupportFunctions.MIBEntryDelete(
IPRTRMGR_PID,
MIB_INFO_SIZE(MIB_PROXYARP),
Buffer
);
Query->rgdwVarIndex[0] = (Address | ~Mask);
Query->rgdwVarIndex[1] = 0xffffffff;
Query->rgdwVarIndex[2] = ((PNAT_INTERFACE)Context)->Index;
NatSupportFunctions.MIBEntryDelete(
IPRTRMGR_PID,
MIB_INFO_SIZE(MIB_PROXYARP),
Buffer
);
}
} // NatpDeleteProxyArpCallback
VOID
NatUpdateProxyArp(
PNAT_INTERFACE Interfacep,
BOOLEAN CreateEntries
)
/*++
Routine Description:
This routine is invoked to install or remove the proxy-ARP entries
corresponding to the address-ranges configured on the given interface.
Arguments:
Interfacep - the interface on which to operate
CreateEntries - TRUE to install entries, FALSE to remove
Return Value:
none.
Environment:
Invoked with the interface list locked by the caller.
--*/
{
ULONG Count;
ULONG Error;
ULONG i;
PIP_NAT_ADDRESS_RANGE Range;
PROFILE("NatUpdateProxyArp");
if (!Interfacep->Info ||
!NatSupportFunctions.MIBEntryCreate ||
!NatSupportFunctions.MIBEntryDelete
) {
return;
}
//
// Locate the address-ranges, if any
//
Error =
MprInfoBlockFind(
&Interfacep->Info->Header,
IP_NAT_ADDRESS_RANGE_TYPE,
NULL,
&Count,
(PUCHAR*)&Range
);
if (Error || NULL == Range) { return; }
//
// Now go through the ranges, decomposing each one
//
for (i = 0; i < Count; i++) {
DecomposeRange(
Range[i].StartAddress,
Range[i].EndAddress,
MostGeneralMask(Range[i].StartAddress, Range[i].EndAddress),
CreateEntries
? NatpCreateProxyArpCallback : NatpDeleteProxyArpCallback,
Interfacep
);
}
} // NatUpdateProxyArp