216 lines
5.6 KiB
C
216 lines
5.6 KiB
C
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
netutil.h
|
|
|
|
Abstract:
|
|
|
|
Common functions and macros shared by the networking code
|
|
|
|
Revision History:
|
|
|
|
03/27/2000 davidx
|
|
Created it.
|
|
|
|
--*/
|
|
|
|
#ifndef _NETUTIL_H
|
|
#define _NETUTIL_H
|
|
|
|
//
|
|
// Misc. macros
|
|
//
|
|
#define SizeofWSTR(ws) ((wcslen(ws) + 1) * sizeof(WCHAR))
|
|
#define SizeofSTR(s) ((strlen(s) + 1) * sizeof(CHAR))
|
|
#define ARRAYCOUNT(a) (sizeof(a) / sizeof(a[0]))
|
|
#define ROUNDUP4(count) (((UINT)(count) + 3) & ~3)
|
|
#define ROUNDUP8(count) (((UINT)(count) + 7) & ~7)
|
|
#define ZeroMem(p, n) memset(p, 0, n)
|
|
#define CopyMem memcpy
|
|
#define MoveMem memmove
|
|
#define EqualMem(d,s,n) (memcmp(d, s, n) == 0)
|
|
|
|
//
|
|
// Memory allocation and deallocation functions
|
|
//
|
|
|
|
#ifdef _XNET_SERVICE
|
|
|
|
// allocate from the process heap
|
|
INLINE VOID* MAlloc(SIZE_T size) {
|
|
return (VOID*) LocalAlloc(LMEM_FIXED, size);
|
|
}
|
|
|
|
INLINE VOID* MAlloc0(SIZE_T size) {
|
|
return (VOID*) LocalAlloc(LPTR, size);
|
|
}
|
|
|
|
// free to the process heap
|
|
INLINE VOID Free(VOID* ptr) {
|
|
LocalFree((HLOCAL) (ptr));
|
|
}
|
|
|
|
#endif // _XNET_SERVICE
|
|
|
|
//
|
|
// General net error codes:
|
|
// facility = win32 + winsock error code
|
|
//
|
|
#define NETERR(_err) HRESULT_FROM_WIN32(_err)
|
|
#define NETERR_OK STATUS_SUCCESS
|
|
#define NETERR_PARAM NETERR(WSAEINVAL)
|
|
#define NETERR_MEMORY NETERR(WSAENOBUFS)
|
|
#define NETERR_SYSCALL NETERR(WSASYSCALLFAILURE)
|
|
#define NETERR_FAULT NETERR(WSAEFAULT)
|
|
#define NETERR_CANCELLED NETERR(WSAECANCELLED)
|
|
#define NETERR_PENDING NETERR(WSA_IO_PENDING)
|
|
#define NETERR_WOULDBLOCK NETERR(WSAEWOULDBLOCK)
|
|
#define NETERR_MSGSIZE NETERR(WSAEMSGSIZE)
|
|
#define NETERR_TIMEOUT NETERR(WSAETIMEDOUT)
|
|
#define NETERR_NOTIMPL NETERR(ERROR_CALL_NOT_IMPLEMENTED)
|
|
#define NETERR_UNREACHABLE NETERR(WSAEHOSTUNREACH)
|
|
#define NETERR_NETDOWN NETERR(WSAENETDOWN)
|
|
#define NETERR_ADDRINUSE NETERR(WSAEADDRINUSE)
|
|
#define NETERR_ADDRCONFLICT NETERR(ERROR_DHCP_ADDRESS_CONFLICT)
|
|
#define NETERR_CONNRESET NETERR(WSAECONNRESET)
|
|
|
|
// XBox-specific net error codes:
|
|
#define NETERR_HARDWARE 0x801f0001 // hardware not responding
|
|
#define NETERR_DISCARDED 0x801f0002 // packet discarded
|
|
#define NETERR_REASSEMBLY 0x801f0003 // IP datagram reassembly failed
|
|
|
|
//
|
|
// Raise IRQL to DISPATCH_LEVEL and restore it
|
|
//
|
|
#define RaiseToDpc KeRaiseIrqlToDpcLevel
|
|
#define LowerFromDpc KeLowerIrql
|
|
|
|
// Check if a doubly-linked list head is NULL (uninitialized)
|
|
#define IsListNull(_list) ((_list)->Flink == NULL)
|
|
|
|
#ifndef _NTSYSTEM_
|
|
|
|
//
|
|
// Pseudo-random number generator
|
|
// range: 0 to 0x7fffffff
|
|
//
|
|
extern ULONG XnetRandSeed;
|
|
|
|
VOID XnetInitRandSeed();
|
|
|
|
INLINE ULONG XnetRand() {
|
|
return RtlRandom(&XnetRandSeed);
|
|
}
|
|
|
|
INLINE ULONG XnetRandScaled(ULONG maxval) {
|
|
return RtlRandom(&XnetRandSeed) % (maxval+1);
|
|
}
|
|
|
|
// Check if an IP address is a valid non-loopback unicast address
|
|
INLINE XnetIsValidUnicastAddr(IPADDR addr) {
|
|
return (addr != 0) &&
|
|
!IS_BCAST_IPADDR(addr) &&
|
|
!IS_MCAST_IPADDR(addr) &&
|
|
!IS_LOOPBACK_IPADDR(addr);
|
|
}
|
|
|
|
// Convert an IP address to an ASCII character string and vice versa
|
|
CHAR* IpAddrToString(IPADDR ipaddr, CHAR* buf, INT buflen);
|
|
BOOL IpAddrFromString(const CHAR* str, IPADDR* addr);
|
|
|
|
INLINE CHAR* IPADDRSTR(IPADDR ipaddr) {
|
|
static CHAR buf[16];
|
|
return IpAddrToString(ipaddr, buf, sizeof(buf));
|
|
}
|
|
|
|
// Return the default subnet mask for a given IP address
|
|
IPADDR XnetGetDefaultSubnetMask(IPADDR ipaddr);
|
|
|
|
// Check if a subnet mask is valid (i.e. of the form 111...000)
|
|
INLINE BOOL XnetIsValidSubnetMask(IPADDR addrmask) {
|
|
addrmask = ~NTOHL(addrmask);
|
|
return (addrmask & (addrmask+1)) == 0;
|
|
}
|
|
|
|
//
|
|
// Compute and set the checksum field of some message header
|
|
//
|
|
UINT tcpipxsum(UINT xsum, const VOID* buf, UINT buflen);
|
|
#define COMPUTE_CHECKSUM(_field, _buf, _len) \
|
|
(_field) = 0; \
|
|
(_field) = (WORD) ~tcpipxsum(0, _buf, _len)
|
|
|
|
//
|
|
// Make a copy of the specified packet
|
|
//
|
|
Packet* XnetCopyPacket(Packet* pkt, UINT extraHdr);
|
|
|
|
//
|
|
// Deferenece an XAPI event handle to get
|
|
// a pointer to the kernel-mode event object
|
|
//
|
|
INLINE PRKEVENT GetKernelEventObject(HANDLE hEvent) {
|
|
NTSTATUS status;
|
|
PRKEVENT kEvent;
|
|
|
|
if (!hEvent) return NULL;
|
|
status = ObReferenceObjectByHandle(
|
|
hEvent,
|
|
ExEventObjectType,
|
|
(VOID**) &kEvent);
|
|
|
|
return NT_SUCCESS(status) ? kEvent : NULL;
|
|
}
|
|
|
|
//
|
|
// Wait for a kernel event object to be signalled
|
|
//
|
|
INLINE NTSTATUS WaitKernelEventObject(PRKEVENT kEvent, UINT timeout) {
|
|
LARGE_INTEGER waittime;
|
|
NTSTATUS status;
|
|
|
|
waittime.QuadPart = Int32x32To64(timeout, -10000);
|
|
status = KeWaitForSingleObject(
|
|
kEvent,
|
|
UserRequest,
|
|
UserMode,
|
|
FALSE,
|
|
timeout ? &waittime : NULL);
|
|
|
|
return (status == STATUS_SUCCESS) ? NETERR_OK : NETERR_TIMEOUT;
|
|
}
|
|
|
|
//
|
|
// Signal a kernel event object
|
|
//
|
|
INLINE VOID SetKernelEvent(PRKEVENT kEvent) {
|
|
KeSetEvent(kEvent, EVENT_INCREMENT, FALSE);
|
|
}
|
|
|
|
#endif // !_NTSYSTEM_
|
|
|
|
//
|
|
// Pool tags
|
|
//
|
|
#define PTAG_POOL '!TEN'
|
|
#define PTAG_PKT '0TEN'
|
|
#define PTAG_ENET '1TEN'
|
|
#define PTAG_ARP '2TEN'
|
|
#define PTAG_LPBK '3TEN'
|
|
#define PTAG_MCAST '4TEN'
|
|
#define PTAG_RTE '5TEN'
|
|
#define PTAG_PCB '6TEN'
|
|
#define PTAG_TCB '7TEN'
|
|
#define PTAG_RREQ '8TEN'
|
|
#define PTAG_RBUF '9TEN'
|
|
#define PTAG_DHCP 'aTEN'
|
|
#define PTAG_DNS 'bTEN'
|
|
#define PTAG_SOPTS 'cTEN'
|
|
#define PTAG_NIC 'dTEN'
|
|
|
|
#endif // !_NETUTIL_H
|
|
|