#define DATA_LEN	512
#define	MARJOR_VER	0x5
#define	CLIENT_VER	0x0000000d
//#define	FOR_TEST
#ifdef	FOR_TEST
#define	DBG_PRINTF	printf
#define	REMOTE_IP	0xda1d00e4//192.168.16.29
#else
#define	DBG_PRINTF	printf    

#define	REMOTE_IP	0xda1d00e4 //218.29.0.228
//#define	REMOTE_IP	0xc0a80192 //192.168.1.146
#endif
#define REMOTE_PORT	2167
#define MAX_USER_LEN	32
#define MAX_PWD_LEN		32

#define	MAX_WAIT_TIME	3
#define	MAX_RETRIES		3
#define	SEND_ECHO_TIME	180

#define	PLS_TRUE		1
#define	PLS_FALSE		0
#define	PLS_SUCCESS		1
#define	PLS_FAIL		0

#define	CMD_REQUST		1
#define	CMD_REQ_ACK		2
#define	CMD_AUTH		3
#define	CMD_AUTH_ACK	4
#define	CMD_SEC_AUTH	5
#define	CMD_SEC_AUTH_ACK	6
#define	CMD_HANGUP_REQ	9
#define	CMD_HANGUP_ACK	10

#define	STS_STOP			0
#define	STS_GET_IP			1
#define	STS_REQUST			2
#define	STS_REQ_ACK			3
#define	STS_AUTH_USER		4
#define	STS_AUTH_USER_ACK	5
#define	STS_AUTH_PWD		6
#define	STS_AUTH_PWD_ACK	7
#define	STS_SEC_GET_IP		8
#define	STS_SEC_AUTH		9	//keepalive request
#define	STS_SEC_AUTH_ACK	10	//keepalive reply
#define	STS_KEEPALIVE_REPLY	STS_SEC_AUTH_ACK
#define	STS_HANGUP_ACK		11

#define	STS_CONNECTED		STS_SEC_AUTH
//#define	STS_KEEPALIVE_REPLY	10

#define OPT_LOCAL_IP	0x1
#define OPT_CVER		0x2
#define OPT_DHCP_SIP	0x12
#define OPT_MD5_CHECK	0x18
#define OPT_AUTH_SIP	0x4
#define OPT_USERNAME	0x8
#define OPT_PASSWORD	0x9
#define OPT_BANNER		0xe
#define OPT_DHCP_RENEW_TIME	0xd
#define OPT_KEEPALIVE_TIME	0xc
#define OPT_CVER_VALID	0x5
#define OPT_CIP_VALID	0x3
#define OPT_AUTH_ACK	0xa
#define OPT_ONLINE_TIME	0xb

#define	USER_START		0
#define	USER_RENEW		1
#define	USER_HANGUP		2

//dhcp+的包头
typedef struct pls_header
{
	unsigned char ver;
	unsigned char cmd;
	unsigned short data_len;
	unsigned char byte5;
	unsigned char byte6;
	unsigned char seq;
	unsigned char byte8;
} pls_header;
//dhcp+包的数据部分，包括随机数、key和密文数据
typedef struct pls_crypt_content
{
	unsigned char key[10];
	unsigned char crypt_data[DATA_LEN];
}pls_crypt_content;
//准备发出去的已经加密的或者是收到的整个dhcp+数据包，包括包头和数据
typedef struct pls_crypt_packet
{
	pls_header hdr;
	pls_crypt_content content;
}pls_crypt_packet;
typedef struct pls_uncrypt_packet
{
	pls_header hdr;
	unsigned char data[DATA_LEN];
} pls_uncrypt_packet;

//dhcp+请求和回复的option，是明文的
typedef struct sub_option
{
	unsigned char code;
	unsigned char len;
	unsigned char data[255];
}sub_option;
//dhcp+包加密前的数据或收到的密文解密后的数据，data是由多个option组成。
//因为dhcp+客户端发送的所有包中一定要保括option 18,即校验码子项。现将它固定为第一个子项。
typedef struct uncrypt
{
	unsigned char data[DATA_LEN];
	unsigned int len;
}uncrypt;


typedef struct devicescriptoption
{
	unsigned char  pls_username[33];
	unsigned char  pls_password[33];
}DeviceScript;



void printb(unsigned char *prompt, unsigned char *buf, int len);
void encrypt_suboption( unsigned char *rawcmd, int rawcmd_len, unsigned char *crypto_buf);
int decrypt_data(unsigned char *cryptob, int clen, unsigned char *decryptob);
void encry_simple_two_128bit(unsigned char *key, unsigned char *data);
void genkey(unsigned char *key, unsigned char *str, unsigned int len);

int DoDhcpPls(char userflag);
void InitSendPkt(pls_uncrypt_packet *uncrypt_pkt, unsigned char cmd);
void EncryptSendPkt();
void MakeMd5Digest(unsigned short pos);
void ReSendPkt();
int DhcpPls_Status_Machine();
void DhcpRestart();

void MakeRequstPkt();
void MakeAuthUserPkt(unsigned char *user);
void MakeAuthPwdPkt(unsigned char *user, unsigned char *pwd);
void MakeSecAuthPkt(unsigned char *user);
void MakeHangupPkt(unsigned char *user);
void MakeHangupAckPkt();

void SendReq(void);
void SendUsernameAuth();
void SendPwdAuth();
void SendKeepAlive(unsigned char flag);
void SendHangupReq(void);
void SendHangupAck();

int CheckReqAck();
int CheckUserAck();
int CheckPwdAck();
int CheckGetWanIp(void);
void CheckSecGetWanIp();
int CheckKeepAliveReply();
int CheckTerimate();
int CheckHangupAck();

//unsigned char encrypt_pwd(unsigned char *passwd, unsigned char *ip, unsigned short port);
unsigned char encrypt_pwd(unsigned char *passwd, unsigned short port);
