/*++ Copyright (c) 1992 Microsoft Corporation Module Name: tftpd.h Abstract: This contains the constants and types for the tftp daemon. Author: Full Name (email name) DD-MMM-YYYY Sam Patton (sampa) 08-apr-1992 Environment: Streams Revision History: dd-mmm-yyy MohsinA, 02-Dec-96, 29-May-97. See discussion in R.Steven's books: - "Unix Network Programming", Prentice Hall, 1990. - TCP/IP Illustrated, Vol 1. Addison Wesley. --*/ #include #include #include #include #include #include #if defined(REMOTE_BOOT_SECURITY) #include #endif //defined(REMOTE_BOOT_SECURITY) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(REMOTE_BOOT_SECURITY) #include #include #include #endif //defined(REMOTE_BOOT_SECURITY) // // max size of a tftp datagram is 2 byte opcode, 2 byte data count, and a // negotiated number of bytes of data // #define MAX_TFTP_DATAGRAM 65468 #define MAX_OACK_PACKET_LENGTH 1460 #define TFTPD_INITIAL_TIMEOUT 1 // seconds #define TFTPD_MAX_TIMEOUT 10 // seconds #define REAPER_INTERVAL_SEC 60 #define MAX_TFTP_DATA (MAX_TFTP_DATAGRAM - 4) // Number of reaper hits before context deleted #define DEAD_CONTEXT_COUNT 4 #define TFTPD_RRQ 1 #define TFTPD_WRQ 2 #define TFTPD_DATA 3 #define TFTPD_ACK 4 #define TFTPD_ERROR 5 #define TFTPD_OACK 6 #define TFTPD_LOGIN 16 #define TFTPD_KEY 17 #define MAX_TFTPD_RETRIES 10 #define TFTPD_ERROR_UNDEFINED 0 #define TFTPD_ERROR_FILE_NOT_FOUND 1 #define TFTPD_ERROR_ACCESS_VIOLATION 2 #define TFTPD_ERROR_DISK_FULL 3 #define TFTPD_ERROR_ILLEGAL_OPERATION 4 #define TFTPD_ERROR_UNKNOWN_TRANSFER_ID 5 #define TFTPD_ERROR_FILE_EXISTS 6 #define TFTPD_ERROR_NO_SUCH_USER 7 #define TFTPD_ERROR_OPTION_NEGOT_FAILED 8 #define NUM_TFTP_ERROR_CODES 9 #define REG_NEW_SOCKET 0x1 #define REG_CONTINUE_SOCKET 0x2 // // Types // typedef struct _TFTP_GLOBALS { CRITICAL_SECTION Lock; //protects r/w access to all fields LIST_ENTRY WorkList; //list of outstanding work contexts HANDLE TimerQueueHandle; } TFTP_GLOBALS, *PTFTP_GLOBALS; typedef struct _TFTP_REQUEST { LIST_ENTRY RequestLinkage; SOCKET TftpdPort; struct sockaddr_in ForeignAddress; IPAddr MyAddr; DWORD BlockSize; DWORD FileSize; int Timeout; DWORD DataSize; //actual size of data of incoming packet HANDLE RcvEvent; //event for WSARecvFrom #if defined(REMOTE_BOOT_SECURITY) ULONG SecurityHandle; char Sign[NTLMSSP_MESSAGE_SIGNATURE_SIZE]; #endif //defined(REMOTE_BOOT_SECURITY) char Packet1[MAX_TFTP_DATAGRAM + 1]; char Packet2[MAX_TFTP_DATAGRAM]; char Packet3[MAX_TFTP_DATAGRAM]; } TFTP_REQUEST, *PTFTP_REQUEST; // ======================================================================== #if defined(REMOTE_BOOT_SECURITY) typedef struct _TFTPD_SECURITY { struct sockaddr_in ForeignAddress; // remote IP address USHORT Validation; // used to check consistency of handles -- 0 means it is not in use BOOLEAN LoginComplete; // have we successfully logged them in BOOLEAN CredentialsHandleValid; BOOLEAN ServerContextHandleValid; BOOLEAN GeneratedKey; SECURITY_STATUS LoginStatus; CtxtHandle ServerContextHandle; CredHandle CredentialsHandle; ULONG ContextAttributes; ULONG Key; // the key if he requests one UCHAR SignedKey[4]; // the signed version of the key UCHAR Sign[NTLMSSP_MESSAGE_SIGNATURE_SIZE]; // the actual sign UCHAR LastFileRead[64]; // the last 64 bytes of the name of the last file read UCHAR LastFileSign[NTLMSSP_MESSAGE_SIGNATURE_SIZE]; // the sign of the filename in the request USHORT LastFileReadPort; // the port it was read on } TFTPD_SECURITY, *PTFTPD_SECURITY; #endif //defined(REMOTE_BOOT_SECURITY) typedef enum _CONTEXT_TYPE_ENUM {NO_CONTEXT,READ_CONTEXT,WRITE_CONTEXT,LOGIN_CONTEXT,KEY_CONTEXT} CONTEXT_TYPE_ENUM; typedef struct _TFTP_CONTEXT_HEADER { CRITICAL_SECTION Lock; LIST_ENTRY ContextLinkage; SOCKET Sock; CONTEXT_TYPE_ENUM ContextType; struct sockaddr_in ForeignAddress; char *Packet; HANDLE SocketEvent; HANDLE WaitEvent; DWORD DueTime; //timeout interval in msecs HANDLE TimerHandle; DWORD IdleCount; //to test if connection died DWORD RetransmissionCount; DWORD RefCount; WORD SendFail; BOOL Closing; } TFTP_CONTEXT_HEADER, *PTFTP_CONTEXT_HEADER; typedef struct _TFTP_READ_WRITE_CONTEXT_HEADER { TFTP_CONTEXT_HEADER ; WORD BlockNumber; DWORD BlockSize; DWORD BytesRead; DWORD packetLength; DWORD oackLength; BOOL FixedTimer; // true if timeout option received int fd; } TFTP_READ_WRITE_CONTEXT_HEADER, *PTFTP_READ_WRITE_CONTEXT_HEADER; //N.B. The first field of ALL following contexts must be TFTP_CONTEXT_HEADER or // TFTP_READ_WRITE_CONTEXT_HEADER typedef struct _TFTP_READ_CONTEXT { // Fields in ALL Contexts TFTP_READ_WRITE_CONTEXT_HEADER ; // Begin Context Specific Data BOOL Done; #if defined(REMOTE_BOOT_SECURITY) DWORD EncryptedBytesSent; char *EncryptFileBuffer; TFTPD_SECURITY Security; int EncryptBytesSent; SecBufferDesc SignMessage; SecBuffer SigBuffers[2]; #endif //defined(REMOTE_BOOT_SECURITY) } TFTP_READ_CONTEXT, *PTFTP_READ_CONTEXT; typedef struct _TFTP_WRITE_CONTEXT { // Fields in All contexts TFTP_READ_WRITE_CONTEXT_HEADER ; // Begin Context Specific Data int FileMode; #if defined(REMOTE_BOOT_SECURITY) TFTPD_SECURITY Security; #endif //defined(REMOTE_BOOT_SECURITY) } TFTP_WRITE_CONTEXT, *PTFTP_WRITE_CONTEXT; typedef struct _TFTP_LOGIN_CONTEXT { // Fields in all contexts TFTP_CONTEXT_HEADER ; // Begin Context Specific Data } TFTP_LOGIN_CONTEXT, *PTFTP_LOGIN_CONTEXT; typedef struct _TFTP_KEY_CONTEXT { // Fields in all contexts TFTP_CONTEXT_HEADER ; // Begin Context Specific Data } TFTP_KEY_CONTEXT, *PTFTP_KEY_CONTEXT; // ======================================================================== struct TFTPD_STAT { time_t started_at; // updated in main. unsigned int req_read; // updated in master. unsigned int req_write; // updated in master. #if defined(REMOTE_BOOT_SECURITY) unsigned int req_login; // updated in master. unsigned int req_key; // updated in master. #endif defined(REMOTE_BOOT_SECURITY) unsigned int req_error; // updated in master. unsigned int req_asc; unsigned int req_bin; unsigned int bytes_sent; unsigned int bytes_recv; unsigned int errors; }; typedef struct { LIST_ENTRY Linkage; SOCKET Sock; IPAddr IPAddress; HANDLE WaitHandle; HANDLE WaitEvent; BOOL Referenced; DWORD Flags; } SocketEntry, *PSocketEntry; // ======================================================================== // // Prototypes // void TftpdReleaseContextLock( PTFTP_CONTEXT_HEADER Context ); void TftpdErrorPacket( struct sockaddr * PeerAddress, char * RequestPacket, SOCKET LocalSocket, unsigned short ErrorCode, char * ErrorMessage OPTIONAL ); DWORD TftpdHandleRead( PVOID ); DWORD TftpdHandleWrite( PVOID ); #if defined(REMOTE_BOOT_SECURITY) DWORD TftpdHandleLogin( PVOID ); DWORD TftpdHandleKey( PVOID ); #endif //defined(REMOTE_BOOT_SECURITY) void s_inet_ntoa( unsigned long, char * ); int TftpdDoRead( int, char *, int, int); int TftpdDoWrite( int, char *, int, int, char *); unsigned long s_inet_addr( char * ); VOID TftpdControlHandler( DWORD); VOID TftpdServiceExit( IN ULONG); DWORD TftpdStart( IN DWORD, IN LPTSTR *); DWORD TftpdInitializeThreadPool(); DWORD TftpdThreadPool(LPVOID); VOID TftpdInitializeReceiveHeap(); DWORD TftpdResumeRead( PTFTP_READ_CONTEXT Context, PTFTP_REQUEST Request ); DWORD TftpdResumeWrite( PTFTP_WRITE_CONTEXT Context, PTFTP_REQUEST Request ); DWORD TftpdResumeLogin( PTFTP_LOGIN_CONTEXT Context, PTFTP_REQUEST Request ); DWORD TftpdResumeKey( PTFTP_KEY_CONTEXT Context, PTFTP_REQUEST Request ); DWORD TftpdNewReceive( PVOID Argument, BYTE Flags ); DWORD TftpdContinueReceive( PVOID Argument, BYTE Flags ); VOID TftpdCleanHeap(); VOID DeleteSocketEntry(SocketEntry *SE); DWORD GetIpTable(PMIB_IPADDRTABLE *AddrTable); SocketEntry* AddSocket(IPAddr Addr); DWORD CleanSocketList(); DWORD LookupSocketEntryBySock(SOCKET Sock, SocketEntry **SE); VOID NTAPI InterfaceChange(PVOID Context, BOOLEAN Flag); HANDLE RegisterSocket(SOCKET Sock, HANDLE Event, DWORD Flag); VOID TftpdReaper(PVOID ReaperContext, BOOLEAN Flag); VOID TftpdFreeContext(PTFTP_CONTEXT_HEADER Context); VOID TftpdRemoveContextFromList(PTFTP_CONTEXT_HEADER Context); VOID TftpdResumeProcessing(PVOID Argument); // // Macros // // // BOOLEAN // CHECK_ACK( // char * Buffer, // unsigned short AckType, // unsigned short BlockNumber); // // This returns TRUE if this Buffer is an ack for this block number. // #define CHECK_ACK(BUFFER, ACK_TYPE, BLOCK_NUMBER) \ ((*((unsigned short *) (BUFFER)) == ntohs((short)ACK_TYPE)) \ && ((((unsigned short *) (BUFFER))[1]) == ntohs((short)(BLOCK_NUMBER)))) extern struct TFTPD_STAT tftpd_stat; extern FILE* LogFile; extern char LogFileName[]; extern BOOL LoggingEvent; #define LEN_DbgPrint 1000 int TftpdPrintLog( char * format, ... ); void TftpdLogEvent( WORD logtype, char message[] ); void BeginLogFile( void ); // #define DbgPrint printf // #define DbgPrint TftpdPrintLog #define DbgPrint // // In dir.c // int ReadRegistryValues( void ); int Set_StartDirectory(void); int match( const char * p, const char * s ); #define TFTPD_DEFAULT_DIR "\\tftpdroot\\" #define TFTPD_LOGFILE "tftpd.log" #define TFTPD_REGKEY "System\\CurrentControlSet\\Services\\tftpd\\parameters" #define TFTPD_REGKEY_DIR "directory" #define TFTPD_REGKEY_CLIENTS "clients" #define TFTPD_REGKEY_MASTERS "masters" #define TFTPD_REGKEY_READABLE "readable" #define TFTPD_REGKEY_WRITEABLE "writable" // // Start directory setup. // extern char StartDirectory[]; extern int StartDirectoryLen; // // Client and file read/write validation. // extern char ValidClients []; extern char ValidMasters []; extern char ValidReadFiles []; extern char ValidWriteFiles[]; // // //