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