|
|
/*++
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
|