2020-09-30 17:17:25 +02:00

409 lines
11 KiB
C

#ifndef __PPP_H__
#define __PPP_H__
#include "lcp.h"
#include "pap.h"
#include "ncp.h"
typedef DWORD IPADDR;
/*
* DEFINES
*/
#define PPP_FLAG_BYTE 0x7E
#define PPP_ESC_BYTE 0x7D
#define READ_TIMEOUT (3 * 60 * 1000)
// Maximum length used for the phone number
#define PNLEN 56
// these constants are used as indecies into the PPP_CP_INFO array
#define CP_LCP 0
#define CP_PAP 1
#define CP_IPCP 2
#define NUM_CP 3
#define PPP_MAX_FAILURE 5
// Add 4 bytes for protocol (1), control (1), and CRC (2)
#define PPP_FRAME_MAX_LEN (LCP_DEFAULT_MRU + 4)
/*
* Framing options
*/
#define PPP_MULTILINK_FRAMING 0x00000010
#define PPP_SHORT_SEQUENCE_HDR_FORMAT 0x00000020
#define PPP_MC_MULTILINK_FRAMING 0x00000040
#define PPP_FRAMING 0x00000100
#define PPP_COMPRESS_ADDRESS_CONTROL 0x00000200
#define PPP_COMPRESS_PROTOCOL_FIELD 0x00000400
#define PPP_ACCM_SUPPORTED 0x00000800
// Various control protocol IDs
#define PPP_LCP_PROTOCOL 0xC021 // Link Control Protocol
#define PPP_PAP_PROTOCOL 0xC023 // Password Authentication Protocol
#define PPP_CBCP_PROTOCOL 0xC029 // Callback Control Protocol
#define PPP_BACP_PROTOCOL 0xC02B // Bandwidth Allocation Control Protocol
#define PPP_BAP_PROTOCOL 0xC02D // Bandwidth Allocation Protocol
#define PPP_CHAP_PROTOCOL 0xC223 // Challenge Handshake Auth. Protocol
#define PPP_IPCP_PROTOCOL 0x8021 // Internet Protocol Control Protocol
#define PPP_ATCP_PROTOCOL 0x8029 // Appletalk Control Protocol
#define PPP_IPXCP_PROTOCOL 0x802B // Novel IPX Control Procotol
#define PPP_NBFCP_PROTOCOL 0x803F // NetBIOS Framing Control Protocol
#define PPP_CCP_PROTOCOL 0x80FD // Compression Control Protocol
#define PPP_SPAP_NEW_PROTOCOL 0xC027 // Shiva PAP new protocol
#define PPP_EAP_PROTOCOL 0xC227 // Extensible Authentication Protocol
// CHAP Digest codes
#define PPP_CHAP_DIGEST_MD5 0x05 // PPP standard MD5
#define PPP_CHAP_DIGEST_MSEXT 0x80 // Microsoft extended CHAP (nonstandard)
#define PPP_CHAP_DIGEST_MSEXT_NEW 0x81 // Microsoft extended CHAP (nonstandard)
// Config Codes
#define CONFIG_REQ 1
#define CONFIG_ACK 2
#define CONFIG_NAK 3
#define CONFIG_REJ 4
#define TERM_REQ 5
#define TERM_ACK 6
#define CODE_REJ 7
#define PROT_REJ 8
#define ECHO_REQ 9
#define ECHO_REPLY 10
#define DISCARD_REQ 11
#define IDENTIFICATION 12
#define TIME_REMAINING 13
typedef enum _PPP_PHASE {
PPP_LCP,
PPP_AP,
PPP_NCP
} PPP_PHASE;
typedef enum _FSM_STATE {
FSM_INITIAL,
FSM_STARTING,
FSM_CLOSED,
FSM_STOPPED,
FSM_CLOSING,
FSM_STOPPING,
FSM_REQ_SENT,
FSM_ACK_RCVD,
FSM_ACK_SENT,
FSM_OPENED
} FSM_STATE;
typedef enum _AP_ACTION {
AP_NoAction, // Be passive, i.e. listen without timeout (default)
AP_Done, // End authentication session, dwError gives result
AP_SendAndDone, // As above but send message without timeout first
AP_Send, // Send message, don't timeout waiting for reply
AP_SendWithTimeout, // Send message, timeout if reply not received
AP_SendWithTimeout2,// As above, but don't increment retry count
AP_Authenticate // Authenticate using specified credentials.
} AP_ACTION;
/*
* STRUCTURES
*/
typedef struct _PPP_FRAME {
BYTE Address;
BYTE Control;
BYTE Data[1];
} PPP_FRAME;
#define PPP_FRAME_HDR_LEN (sizeof(PPP_FRAME) - 1)
typedef struct _PPP_PACKET {
BYTE Protocol[2]; // Protocol Number
BYTE Data[1]; // Data
} PPP_PACKET;
#define PPP_PACKET_HDR_LEN (sizeof(PPP_PACKET) - 1)
typedef struct _PPP_CONFIG {
BYTE Code; // Config code
BYTE Id; // ID of this config packet
BYTE Length[2]; // Length of this packet
BYTE Data[1]; // Data
} PPP_CONFIG;
#define PPP_CONFIG_HDR_LEN (sizeof(PPP_CONFIG) - 1)
typedef struct _PPP_OPTION {
BYTE Type; // Option Code
BYTE Length; // Length of this option packet
BYTE Data[1]; // Data
} PPP_OPTION;
#define PPP_OPTION_HDR_LEN (sizeof(PPP_OPTION) - 1)
typedef struct _PPP_RECEIVED PPP_RECEIVED;
typedef struct _PPP_RECEIVED {
PPP_RECEIVED *pNext;
PPP_RECEIVED *pPrev;
DWORD iCrc;
DWORD cb;
Packet *pkt;
} PPP_RECEIVED;
typedef struct _PPP_CP_INFO {
// Protocol number for this CP
DWORD Protocol;
// Recognize options up to this number.
DWORD Recognize;
// Initialize all work values.
DWORD (*CP_Begin)(VOID);
// Free any allocated data.
DWORD (*CP_End)(VOID);
// When leaving Initial or Stopped states. May be NULL.
DWORD (*CP_ThisLayerStarted)(VOID);
// When entering Closed or Stopped states. May be NULL
DWORD (*CP_ThisLayerFinished)(VOID);
// When entering the Opened state. May be NULL.
DWORD (*CP_ThisLayerUp)(VOID);
// When leaving the Opened state. May be NULL.
DWORD (*CP_ThisLayerDown)(VOID);
// Called to make a configure request.
DWORD (*CP_MakeConfigRequest)(PPP_CONFIG *pRequestBuf, DWORD cbRequestBuf);
// Called when configure request is received and a result packet
// Ack/Nak/Reject needs to be sent
DWORD (*CP_MakeConfigResult)(PPP_CONFIG *pReceiveBuf, PPP_CONFIG *pResultBuf,
DWORD cbResultBuf, BOOL fRejectNaks);
// Called to process an Ack that was received.
DWORD (*CP_ConfigAckReceived)(PPP_CONFIG *pReceiveBuf);
// Called to process a Nak that was received.
DWORD (*CP_ConfigNakReceived)(PPP_CONFIG *pReceiveBuf);
// Called to process a Rej that was received.
DWORD (*CP_ConfigRejReceived)(PPP_CONFIG *pReceiveBuf);
DWORD (*CP_MakeMessage)(PPP_CONFIG *pReceiveBuf);
} PPP_CP_INFO;
typedef struct _AP_INFO {
AP_ACTION Action;
PAP_STATE State;
} AP_INFO;
typedef struct _PPP_INFO {
CHAR szUsername[UNLEN + 1];
CHAR szPassword[PWLEN + 1];
CHAR szDomain[DNLEN + 1];
CHAR szNumber[PNLEN + 1];
PPP_PHASE Phase;
FSM_STATE State;
DWORD dwError;
BYTE Id;
BYTE LastId;
DWORD NakRetryCount;
DWORD RejRetryCount;
DWORD ConfigRetryCount;
DWORD TermRetryCount;
PPP_FRAME *pFrame;
} PPP_INFO;
typedef struct _READ_QUEUE {
HANDLE hEvent;
DWORD nHdr;
DWORD nCrc;
DWORD nOk;
PPP_RECEIVED *pReceived;
PPP_RECEIVED *pReceivedFirst;
PPP_RECEIVED *pReceivedLast;
} READ_QUEUE;
typedef struct _PPP_TIMER {
DWORD Expire;
DWORD Timeout;
} PPP_TIMER;
typedef struct _FRAMING_INFO {
DWORD SendAccm;
DWORD RecvAccm;
UINT fSendPfc : 1;
UINT fSendAcfc : 1;
UINT fRecvPfc : 1;
UINT fRecvAcfc : 1;
} FRAMING_INFO;
typedef struct _IP_INFO {
IfInfo *ifp;
IPADDR IpAddrRemote;
IPADDR IpAddrLocal;
IPADDR IpAddrDns;
} IP_INFO;
// auth.cpp
BOOL ApStart(DWORD CpIndex);
VOID ApReset(VOID);
VOID ApWork(DWORD CpIndex, PPP_CONFIG *pRecvConfig);
// pap.cpp
VOID GetPapInfo(PPP_CP_INFO *pInfo);
// lcp.cpp
VOID GetLcpInfo(PPP_CP_INFO *pInfo);
// worker.cpp
DWORD WorkerThread(LPVOID pThreadParameter);
BOOL SendFrame(DWORD dwLength);
VOID SetTimeout(VOID);
VOID ClearTimeout(VOID);
// hostwire.cpp
VOID HostToWireFormat16(WORD wHostFormat, PBYTE pWireFormat);
VOID HostToWireFormat32(DWORD dwHostFormat, PBYTE pWireFormat);
WORD WireToHostFormat16(PBYTE pWireFormat);
DWORD WireToHostFormat32(PBYTE pWireFormat);
// string.cpp
char* str_search(const char *str1, const char *str2);
char* str_add(char *s1, const char *s2);
// modem.cpp
BOOL InitModem(VOID);
BOOL DialModem(VOID);
BOOL HangupModem(VOID);
// misc.cpp
VOID InitRestartCounters(VOID);
DWORD GetCpIndexFromProtocol(DWORD dwProtocol);
VOID EncodePw(CHAR* pszPassword);
VOID DecodePw(CHAR* pszPassword);
// smaction.cpp
BOOL FsmSendConfigReq(DWORD CpIndex);
BOOL FsmSendTermReq(DWORD CpIndex);
BOOL FsmSendTermAck(DWORD CpIndex, PPP_CONFIG *pRecvConfig);
BOOL FsmSendConfigResult(DWORD CpIndex, PPP_CONFIG *pRecvConfig, BOOL *pfAcked);
BOOL FsmSendEchoReply(DWORD CpIndex, PPP_CONFIG *pRecvConfig);
BOOL FsmSendCodeReject(DWORD CpIndex, PPP_CONFIG *pRecvConfig);
BOOL FsmSendProtocolRej(PPP_PACKET *pPacket, DWORD dwPacketLength);
BOOL FsmInit(DWORD CpIndex);
BOOL FsmReset(DWORD CpIndex);
BOOL FsmThisLayerUp(DWORD CpIndex);
BOOL FsmThisLayerDown(DWORD CpIndex);
BOOL FsmThisLayerStarted(DWORD CpIndex);
BOOL FsmThisLayerFinished(DWORD CpIndex);
/// smevents.cpp
VOID FsmUp(DWORD CpIndex);
VOID FsmOpen(DWORD CpIndex);
VOID FsmDown(DWORD CpIndex);
VOID FsmClose(DWORD CpIndex);
// ncp.cpp
VOID GetIpcpInfo(PPP_CP_INFO *pInfo);
BOOL NcpStart(DWORD CpIndex);
VOID NcpReset(VOID);
// net.cpp
BOOL InitNet(VOID);
// receive.cpp
VOID ReceiveConfigReq(DWORD CpIndex, PPP_CONFIG *pRecvConfig);
VOID ReceiveConfigAck(DWORD CpIndex, PPP_CONFIG *pRecvConfig);
VOID ReceiveConfigNakRej(DWORD CpIndex, PPP_CONFIG *pRecvConfig);
VOID ReceiveTermReq(DWORD CpIndex, PPP_CONFIG *pConfig);
VOID ReceiveTermAck(DWORD CpIndex, PPP_CONFIG *pRecvConfig);
VOID ReceiveUnknownCode(DWORD CpIndex, PPP_CONFIG *pConfig);
VOID ReceiveDiscardReq(DWORD CpIndex, PPP_CONFIG *pConfig);
VOID ReceiveEchoReq(DWORD CpIndex, PPP_CONFIG *pConfig);
VOID ReceiveEchoReply(DWORD CpIndex, PPP_CONFIG *pConfig);
VOID ReceiveCodeRej(DWORD CpIndex, PPP_CONFIG *pConfig);
VOID ReceiveProtocolRej(PPP_PACKET *pPacket);
VOID FsmReceive(PPP_PACKET *pPacket, DWORD dwPacketLength);
BOOL FsmConfigResultReceived(DWORD CpIndex, PPP_CONFIG *pRecvConfig);
// frame.cpp
VOID DecodeFrame(PBYTE pIn, DWORD *pcb);
VOID EncodeFrame(PBYTE pIn, PBYTE pOut, DWORD *pcb);
BOOL CheckCrc(PBYTE pb, DWORD cb);
/*
* GLOBALS
*/
extern PPP_INFO gInfo;
extern PPP_CP_INFO gCpTable[NUM_CP];
extern LCP_INFO gLcp;
extern READ_QUEUE gQueue;
extern PPP_TIMER gTimer;
extern FRAMING_INFO gFraming;
extern AP_INFO gAp;
extern IP_INFO gIp;
/*
* INLINES
*/
// Allocate from the process heap
inline PVOID Alloc(SIZE_T size)
{
return (PVOID)LocalAlloc(LPTR, size);
}
// Free to the process heap
inline VOID Free(PVOID p)
{
LocalFree((HLOCAL)p);
}
inline BYTE GetId(VOID)
{
return ++gInfo.Id;
}
inline BOOL IsLcpOpened(VOID)
{
return (gInfo.Phase == PPP_LCP);
}
inline PPP_PACKET* GetSendPacket(VOID)
{
return (PPP_PACKET*)(gInfo.pFrame->Data);
}
inline DWORD GetMagicNumber(VOID)
{
DWORD dwMagic = XnetRand();
if (dwMagic == 0) {
dwMagic = 29;
}
return dwMagic;
}
#endif // __PPP_H__