windows-nt/Source/XPSP1/NT/net/rras/ip/nat/edithlp.h
2020-09-26 16:20:57 +08:00

107 lines
2.8 KiB
C

/*++
Copyright (c) 1997, Microsoft Corporation
Module Name:
edithlp.h
Abstract:
This module contains helper-declarations for the NAT's built-in editors.
Author:
Abolade Gbadegesin (t-abolag) 25-Aug-1997
Revision History:
--*/
#ifndef _NAT_EDITHLP_H_
#define _NAT_EDITHLP_H_
//
// Macro: COPY_FROM_BUFFER
//
// This macro copies from a buffer-chain to a flat buffer.
//
#define \
COPY_FROM_BUFFER( \
Destination, \
Source, \
Length, \
Offset \
) \
{ \
PUCHAR _Destination = Destination; \
ULONG _Length = Length; \
LONG _Offset = Offset; \
IPRcvBuf* _Source = Source; \
while ((LONG)_Source->ipr_size < _Offset) { \
_Offset -= _Source->ipr_size; \
_Source = _Source->ipr_next; \
} \
while (_Length) { \
ULONG Bytes = min(_Length, _Source->ipr_size-_Offset); \
RtlCopyMemory(_Destination, _Source->ipr_buffer+_Offset, Bytes);\
_Length -= Bytes; \
_Destination += Bytes; \
_Source = _Source->ipr_next; \
_Offset = 0; \
} \
}
//
// Macro: FIND_HEADER_FIELD
//
// This macro initializes a pseudo header's 'Field' member with the address
// in a buffer chain of the corresponding application-header field.
// It is assumed that each field of the application-header is aligned
// on the natural boundary for its width (e.g. 32-bit fields aligned
// on 32-bit boundaries).
//
// 'RecvBuffer' gives the first buffer in the chain containing the field,
// and 'DataOffsetp' points to the (negative) offset into 'RecvBuffer'
// of the header. This offset would be negative if the header is spread
// over multiple buffers and 'RecvBuffer' is one of the later buffers.
//
// The macro advances through the buffer chain until it finds the buffer
// containing the field (using FIELD_OFFSET). It then initializes the
// pseudo-header's field pointer with the position of the field
// (i.e. 'Header->Field = &(field in buffer-chain)).
//
// Given that it walks the buffer chain, the macro thus requires that
// the pseudo-header's field pointers be initialized in-order,
// since an earlier field cannot be found in the chain after we have
// passed the buffer containing the latter while searching for a later field.
//
#define \
FIND_HEADER_FIELD( \
RecvBuffer, \
DataOffsetp, \
Header, \
Field, \
HeaderType, \
FieldType \
) \
while ((LONG)(RecvBuffer)->ipr_size < \
*(DataOffsetp) + FIELD_OFFSET(HeaderType, Field) \
) { \
*(DataOffsetp) -= (RecvBuffer)->ipr_size; \
(RecvBuffer) = (RecvBuffer)->ipr_next; \
if (!(RecvBuffer)) { break; } \
} \
if (RecvBuffer) { \
(Header)->Field = \
(FieldType)((RecvBuffer)->ipr_buffer + *(DataOffsetp) + \
FIELD_OFFSET(HeaderType, Field)); \
}
#endif // _NAT_EDITHLP_H_