text: // SoftEther VPN Source Code - Stable Edition Repository
  // Kernel Device Driver
  // 
  // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
  // 
  // Copyright (c) Daiyuu Nobori.
  // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
  // Copyright (c) SoftEther Corporation.
  // Copyright (c) all contributors on SoftEther VPN project in GitHub.
  // 
  // All Rights Reserved.
  // 
  // http://www.softether.org/
  // 
  // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
  // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
  // 
  // License: The Apache License, Version 2.0
  // https://www.apache.org/licenses/LICENSE-2.0
  // 
  // DISCLAIMER
  // ==========
  // 
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  // SOFTWARE.
  // 
  // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
  // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
  // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
  // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
  // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
  // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
  // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
  // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
  // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
  // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
  // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
  // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
  // LAW OR COURT RULE.
  // 
  // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
  // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
  // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
  // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
  // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
  // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
  // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
  // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
  // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
  // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
  // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
  // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
  // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
  // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
  // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
  // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
  // STATEMENT FOR WARNING AND DISCLAIMER.
  // 
  // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
  // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
  // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
  // 
  // 
  // SOURCE CODE CONTRIBUTION
  // ------------------------
  // 
  // Your contribution to SoftEther VPN Project is much appreciated.
  // Please send patches to us through GitHub.
  // Read the SoftEther VPN Patch Acceptance Policy in advance:
  // http://www.softether.org/5-download/src/9.patch
  // 
  // 
  // DEAR SECURITY EXPERTS
  // ---------------------
  // 
  // If you find a bug or a security vulnerability please kindly inform us
  // about the problem immediately so that we can fix the security problem
  // to protect a lot of users around the world as soon as possible.
  // 
  // Our e-mail address for security reports is:
  // softether-vpn-security [at] softether.org
  // 
  // Please note that the above e-mail address is not a technical support
  // inquiry address. If you need technical assistance, please visit
  // http://www.softether.org/ and ask your question on the users forum.
  // 
  // Thank you for your cooperation.
  // 
  // 
  // NO MEMORY OR RESOURCE LEAKS
  // ---------------------------
  // 
  // The memory-leaks and resource-leaks verification under the stress
  // test has been passed before release this source code.
  
  
  // Neo6.h
  // Header of Neo6.c
  
  #ifndef	NEO_H
  #define	NEO_H
  
  
  // Identification string (NDIS)
  #define	NDIS_NEO_HARDWARE_ID				"VPN Client Adapter - %s"
  #define	NDIS_NEO_DEVICE_NAME				"\\Device\\NEO_%s_DEVICE"
  #define	NDIS_NEO_DEVICE_NAME_WIN32			"\\DosDevices\\NEO_%s_DEVICE"
  #define	NDIS_NEO_DEVICE_FILE_NAME			"\\\\.\\NEO_NEOADAPTER_%s_DEVICE"
  #define	NDIS_NEO_EVENT_NAME					"\\BaseNamedObjects\\NEO_EVENT_%s"
  #define	NDIS_NEO_EVENT_NAME_WIN32			"Global\\NEO_EVENT_NEOADAPTER_%s"
  
  // Constant
  #define	NEO_MAX_PACKET_SIZE			1600
  #define	NEO_MAX_PACKET_SIZE_ANNOUNCE	1514
  #define	NEO_MIN_PACKET_SIZE			14
  #define	NEO_PACKET_HEADER_SIZE		14
  #define	NEO_MAX_FRAME_SIZE			(NEO_MAX_PACKET_SIZE - NEO_MIN_PACKET_SIZE)
  #define	NEO_MAX_SPEED_DEFAULT		100000000ULL
  #define	NEO_MAC_ADDRESS_SIZE		6
  #define	NEO_MAX_MULTICASE			32
  
  
  // IOCTL constant
  #define	NEO_IOCTL_SET_EVENT			CTL_CODE(0x8000, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
  #define	NEO_IOCTL_PUT_PACKET		CTL_CODE(0x8000, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
  #define	NEO_IOCTL_GET_PACKET		CTL_CODE(0x8000, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
  
  
  // Packet data exchange related
  #define	NEO_MAX_PACKET_EXCHANGE		256			// Number of packets that can be exchanged at a time
  #define	NEO_MAX_PACKET_QUEUED		4096		// Maximum number of packets that can be queued
  #define	NEO_EX_SIZEOF_NUM_PACKET	4			// Packet count data (UINT)
  #define	NEO_EX_SIZEOF_LENGTH_PACKET	4			// Length data of the packet data (UINT)
  #define	NEO_EX_SIZEOF_LEFT_FLAG		4			// Flag to indicate that the packet is still
  #define	NEO_EX_SIZEOF_ONE_PACKET	1600		// Data area occupied by a packet data
  #define	NEO_EXCHANGE_BUFFER_SIZE	(NEO_EX_SIZEOF_NUM_PACKET + NEO_EX_SIZEOF_LEFT_FLAG +	\
  	(NEO_EX_SIZEOF_LENGTH_PACKET + NEO_EX_SIZEOF_ONE_PACKET) * (NEO_MAX_PACKET_EXCHANGE + 1))
  #define	NEO_NUM_PACKET(buf)			(*((UINT *)((UCHAR *)buf + 0)))
  #define	NEO_SIZE_OF_PACKET(buf, i)	(*((UINT *)((UCHAR *)buf + NEO_EX_SIZEOF_NUM_PACKET + \
  									(i * (NEO_EX_SIZEOF_LENGTH_PACKET + NEO_EX_SIZEOF_ONE_PACKET)))))
  #define	NEO_ADDR_OF_PACKET(buf, i)	(((UINT *)((UCHAR *)buf + NEO_EX_SIZEOF_NUM_PACKET + \
  									NEO_EX_SIZEOF_LENGTH_PACKET +	\
  									(i * (NEO_EX_SIZEOF_LENGTH_PACKET + NEO_EX_SIZEOF_ONE_PACKET)))))
  #define	NEO_LEFT_FLAG(buf)			NEO_SIZE_OF_PACKET(buf, NEO_MAX_PACKET_EXCHANGE)
  
  
  
  // Definitions needed to compile as a device driver
  #ifdef	NEO_DEVICE_DRIVER
  
  // OS decision
  #ifdef	WIN32
  #define	OS_WIN32	// Microsoft Windows
  #else
  #define	OS_UNIX		// UNIX / Linux
  #endif
  
  
  // Type declaration
  #ifndef	WINDOWS_H_INCLUDED
  #ifndef	WIN9X
  typedef	unsigned long		BOOL;
  #endif	// WIN9X
  #define	TRUE				1
  #define	FALSE				0
  #endif
  typedef	unsigned long		bool;
  #define	true				1
  #define	false				0
  typedef	unsigned long long	UINT64;
  typedef	signed long long	INT64;
  typedef	unsigned short		WORD;
  typedef	unsigned short		USHORT;
  typedef	signed short		SHORT;
  typedef	unsigned char		BYTE;
  typedef	unsigned char		UCHAR;
  typedef signed char			CHAR;
  typedef	unsigned long		DWORD;
  #define	INFINITE			0xFFFFFFFF
  
  #define	LESS(a, max_value)	((a) < (max_value) ? (a) : (max_value))
  #define	MORE(a, min_value)	((a) > (min_value) ? (a) : (min_value))
  #define	INNER(a, b, c)		(((b) <= (c) && (a) >= (b) && (a) <= (c)) || ((b) >= (c) && (a) >= (c) && (a) <= (b)))
  #define	OUTER(a, b, c)		(!INNER((a), (b), (c)))
  #define	MAKESURE(a, b, c)		(((b) <= (c)) ? (MORE(LESS((a), (c)), (b))) : (MORE(LESS((a), (b)), (c))))
  #define	MIN(a, b)			((a) >= (b) ? (b) : (a))
  #define	MAX(a, b)			((a) >= (b) ? (a) : (b))
  #define	EQUAL_BOOL(a, b)	(((a) && (b)) || ((!(a)) && (!(b))))
  
  #ifdef	OS_WIN32
  // NDIS 5.0 related
  #include "NDIS6.h"
  #endif	// OS_WIN32
  
  // Lock
  typedef struct _NEO_LOCK
  {
  #ifdef	OS_WIN32
  	NDIS_SPIN_LOCK spin_lock;
  #endif
  } NEO_LOCK;
  
  // Event
  typedef struct _NEO_EVENT
  {
  #ifdef	OS_WIN32
  #ifndef	WIN9X
  	KEVENT *event;
  	HANDLE event_handle;
  #else	// WIN9X
  	DWORD win32_event;
  #endif	// WIN9X
  #endif
  } NEO_EVENT;
  
  // Packet queue
  typedef struct _NEO_QUEUE
  {
  	struct _NEO_QUEUE *Next;
  	UINT Size;
  	void *Buf;
  } NEO_QUEUE;
  
  // Status
  typedef struct _NEO_STATUS
  {
  	UINT NumPacketSend;
  	UINT NumPacketRecv;
  	UINT NumPacketSendError;
  	UINT NumPacketRecvError;
  	UINT NumPacketRecvNoBuffer;
  	UINT64 Int64NumRecvError;		// ifInErrors, OID_GEN_RCV_ERROR
  	UINT64 Int64BytesRecvTotal;		// ifHCInOctets, OID_GEN_BYTES_RCV
  	UINT64 Int64NumRecvUnicast;		// ifHCInUcastPkts, OID_GEN_DIRECTED_FRAMES_RCV
  	UINT64 Int64NumRecvBroadcast;	// ifHCInBroadcastPkts, OID_GEN_BROADCAST_FRAMES_RCV
  	UINT64 Int64BytesSendTotal;		// ifHCOutOctets, OID_GEN_BYTES_XMIT
  	UINT64 Int64NumSendUnicast;		// ifHCOutUcastPkts, OID_GEN_DIRECTED_FRAMES_XMIT
  	UINT64 Int64NumSendBroadcast;	// ifHCOutBroadcastPkts, OID_GEN_BROADCAST_FRAMES_XMIT
  	UINT64 Int64NumSendError;		// ifOutErrors, OID_GEN_XMIT_ERROR
  	UINT64 Int64BytesRecvUnicast;	// ifHCInUcastOctets, OID_GEN_DIRECTED_BYTES_RCV
  	UINT64 Int64BytesRecvBroadcast;	// ifHCInBroadcastOctets, OID_GEN_BROADCAST_BYTES_RCV
  	UINT64 Int64BytesSendUnicast;	// ifHCOutUcastOctets, OID_GEN_DIRECTED_BYTES_XMIT
  	UINT64 Int64BytesSendBroadcast;	// ifHCOutBroadcastOctets, OID_GEN_BROADCAST_BYTES_XMIT
  } NEO_STATUS;
  
  // NDIS packet buffer
  typedef struct _PACKET_BUFFER
  {
  	NDIS_HANDLE NetBufferListPool;		// NET_BUFFER_LIST Pool
  	NET_BUFFER_LIST *NetBufferList;		// NET_BUFFER_LIST
  } PACKET_BUFFER;
  
  // Context
  typedef struct _NEO_CTX
  {
  	NEO_EVENT *Event;					// Packet reception notification event
  	volatile BOOL Opened;				// Flag of whether opened
  	volatile BOOL Paused;				// Flag of whether paused
  	volatile BOOL Inited;				// Initialization flag
  	volatile BOOL Initing;				// Starting-up flag
  	volatile BOOL Halting;				// Stopping flag
  	volatile UINT NumCurrentDispatch;	// Number of current dispatch requests
  	BYTE MacAddress[6];					// MAC address
  	BYTE padding[2];					// padding
  	NEO_QUEUE *PacketQueue;				// Transmit packet queue
  	NEO_QUEUE *Tail;					// Tail of the transmission packet queue
  	UINT NumPacketQueue;				// Number of queued packet
  	NEO_LOCK *PacketQueueLock;			// Transmit packet queue lock
  	NEO_STATUS Status;					// Status
  	UINT CurrentPacketFilter;			// Current packet filter value
  	UINT CurrentProtocolOptions;		// Current protocol option value
  	BOOL Connected, ConnectedOld;		// Cable connection state
  	BOOL ConnectedForce;				// Connection state forcibly notification
  #ifdef	OS_WIN32
  	NDIS_HANDLE NdisMiniportDriverHandle;	// NDIS miniport driver handle
  	NDIS_HANDLE NdisControl;			// NDIS control handle
  	NDIS_HANDLE NdisMiniport;			// NDIS miniport handle
  	NDIS_HANDLE NdisContext;			// NDIS context handle
  	DEVICE_OBJECT *NdisControlDevice;	// NDIS control device
  	PDRIVER_DISPATCH DispatchTable[IRP_MJ_MAXIMUM_FUNCTION];
  	PACKET_BUFFER *PacketBuffer[NEO_MAX_PACKET_EXCHANGE];		// NDIS packet buffer
  	NDIS_HARDWARE_STATUS HardwareStatus;	// Hardware state
  	char HardwareID[MAX_SIZE];			// Hardware ID
  	char HardwareID_Raw[MAX_SIZE];		// Original hardware ID
  	char HardwarePrintableID[MAX_SIZE];	// Hardware ID (for display)
  #endif
  } NEO_CTX;
  
  extern NEO_CTX *ctx;
  
  
  // Neo.c routine
  void NeoNewStatus(NEO_STATUS *s);
  void NeoFreeStatus(NEO_STATUS *s);
  BOOL NeoInit();
  void NeoShutdown();
  void NeoInitPacketQueue();
  void NeoFreePacketQueue();
  void NeoClearPacketQueue(bool no_lock);
  void NeoLockPacketQueue();
  void NeoUnlockPacketQueue();
  NEO_QUEUE *NeoGetNextQueue();
  void NeoFreeQueue(NEO_QUEUE *q);
  void NeoInsertQueue(void *buf, UINT size);
  UINT NeoGetNumQueue();
  void NeoStartAdapter();
  void NeoStopAdapter();
  void NeoRead(void *buf);
  void NeoWrite(void *buf);
  
  // Common routine (platform dependent)
  void *NeoMalloc(UINT size);
  void *NeoZeroMalloc(UINT size);
  void NeoFree(void *p);
  void NeoCopy(void *dst, void *src, UINT size);
  void NeoZero(void *dst, UINT size);
  NEO_LOCK *NeoNewLock();
  void NeoLock(NEO_LOCK *lock);
  void NeoUnlock(NEO_LOCK *lock);
  void NeoFreeLock(NEO_LOCK *lock);
  NEO_EVENT *NeoNewEvent(char *name);
  NEO_EVENT *NeoCreateWin9xEvent(DWORD h);
  void NeoFreeEvent(NEO_EVENT *event);
  void NeoSet(NEO_EVENT *event);
  void NeoReset(NEO_EVENT *event);
  
  #endif	// NEO_DEVICE_DRIVER
  
  
  #endif	// NEO_H
  
  
  
  