#include <stdio.h>
#include "telnet.h"
#include "command.h"
char resultBuf[4096] = {0};
int main(int argc, char *argv[])
{
char *store;
// telnet_command_init();
parse_cmd_resp_packet("show DeviceInfo;", "AdditionalSoftwareVersion", store);
return 0;
}
/*--------------------------command.c---------------------------------------------------*/
#include "telnet.h"
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#define SERVER_IP "192.168.100.111" //板子的IP
#define SERVER_PORT 50000
#define RECV_SIZE 4096
#define SEND_SIZE 2048
int telnet_command_init(void)
{
int ret;
extern int m_sock_fd;
char send_buff[SEND_SIZE] = {0};
char recv_buff[RECV_SIZE] = {0};
while(1)
{
Reconnection:
sock_client_free();
ret = telnet_client_init(SERVER_IP, SERVER_PORT);
if(0 == ret)
{
PDEBUG(L_CRIT, "Telnet client init was failed!\n");
sleep(1);
continue;
}
PDEBUG(L_DEBUG, "Telnet client init was successful!\n");
while(1)
{
strcpy(recv_buff, "");
ret = TelnetRecv(recv_buff);
if(ret < 0)
{
PDEBUG(L_CRIT, "Telnet client recv messages were error!\n");
continue;
}
else if(0 == ret)
{
PDEBUG(L_WARNING, "Telnet link were shutdown by peer server, create telnet link again!\n");
goto Reconnection;
}
PDEBUG(L_DEBUG, "recv buff: %s\n", recv_buff);
if(strstr(recv_buff, "user"))
{
strcat(send_buff, "webroot\r\n");
TelnetSend(send_buff);
continue;
}
if(strstr(recv_buff, "pwd"))
{
strcat(send_buff, "webroot\r\n");
TelnetSend(send_buff);
strcat(send_buff, "show DeviceInfo;");
recv(m_sock_fd, recv_buff, RECV_SIZE, MSG_WAITALL);
return 1;
}
}
}
return 0;
}
int telnet_send_cmd_mesg(const char* command, char* resp)
{
int ret = 0;
extern int m_sock_fd;
char recv_buff[RECV_SIZE] = {0};
char send_buff[SEND_SIZE] = {0};
if(-1 == m_sock_fd)
{
while(1)
{
ret = telnet_command_init();
if(0 == ret)
{
PDEBUG(L_CRIT, "Telnet client init was failed!\n");
sleep(1);
continue;
}
break;
}
}
if(NULL == command)
{
PDEBUG(L_CRIT, "Telnet command was NULL, please confirm the command is right!\n");
return 0;
}
memset(send_buff, 0, sizeof(send_buff));
strncpy(send_buff, command, sizeof(send_buff));
strncat(send_buff, "\r\n", sizeof(send_buff));
ret = send(m_sock_fd, send_buff, strlen(send_buff), MSG_NOSIGNAL);
if(ret < 0)
{
PDEBUG(L_WARNING, "Socket client send messages was failed, convert telnet type to send message continue!\n");
if(m_sock_fd < 0)
{
while(1)
{
if(!telnet_command_init())
{
PDEBUG(L_CRIT, "Telnet client init was failed!\n");
sleep(1);
continue;
}
break;
}
}
ret = TelnetSend(send_buff);
if(0 == ret)
{
PDEBUG(L_CRIT, "Telnet client send message were failed!\n");
return 0;
}
}
while(1)
{
ret = recv(m_sock_fd, recv_buff, RECV_SIZE, MSG_WAITALL);
// PDEBUG(L_DEBUG, "recv messages: %s\n", recv_buff);
if(-1 == ret && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK ||errno==2))
continue;
if(0 == ret)
{
PDEBUG(L_WARNING, "the connect were shutdown by peer server!\n");
if(0 == telnet_command_init())
{
PDEBUG(L_CRIT, "telnet command init was failed!\n");
return 0;
}
ret = send(m_sock_fd, send_buff, strlen(send_buff), 0);
if(ret < 0)
{
PDEBUG(L_WARNING, "Socket client send messages was failed, convert telnet type to send message continue!\n");
ret = TelnetSend(send_buff);
if(0 == ret)
{
PDEBUG(L_CRIT, "telnet send messages were failed!\n");
return 0;
}
continue;
}
}
else if(ret < 0)
{
PDEBUG(L_WARNING, "Socket client recv messages was failed, continue recv ...\n");
continue;
}
if(NULL != strstr(recv_buff, "#"))
{
strncpy(resp, recv_buff, RECV_SIZE);
break;
}
continue;
}
return 1;
}
int command_init(const char *cmd, char *resp)
{
int ret;
ret = telnet_command_init();
if(0 == ret)
{
PDEBUG(L_CRIT, "telnet_command_init was failed!\n");
return 0;
}
ret = telnet_send_cmd_mesg(cmd, resp);
if(0 == ret)
{
PDEBUG(L_CRIT, "telnet_send_cmd_mesg was failed!\n");
return 0;
}
return 1;
}
int parse_cmd_resp_packet(const char *cmd, const char *key, void *store)
{
int ret;
int i;
char *substr, *ptr;
char tmp[RECV_SIZE] = {0};
char rcv_buf[RECV_SIZE] = {0};
ret = telnet_send_cmd_mesg(cmd, rcv_buf);
if(0 == ret)
{
PDEBUG(L_CRIT, "telnet send command was failed!\n");
return 0;
}
PDEBUG(L_DEBUG, "recv buff: %s\n", rcv_buf);
//the rcv messages were by divided "\r\n", if there are n num"\r\n", there are (n + 1) partions;
substr = strtok(rcv_buf, "\r\n");
if(NULL == substr)
{
PDEBUG(L_CRIT, "Not found the sub string!\n");
return 0;
}
//decide the respond messages by the first line;
ptr = strstr(substr, "error");
if(ptr)
{
PDEBUG(L_CRIT, "the respond messages were error!\n");
return 0;
}
// the substr pointed to each line;
while(substr)
{
substr = strtok(NULL, "\r\n");
ptr = strstr(substr, key);
if(ptr)
{
PDEBUG(L_DEBUG, "%s\n", substr);
ptr = strtok(substr, "=");
if(NULL == ptr)
{
PDEBUG(L_CRIT, "Not found the sub string!\n");
return 0;
}
ptr = strtok(NULL, "=");
if(NULL == ptr)
{
PDEBUG(L_CRIT, "Not found the sub string!\n");
return 0;
}
PDEBUG(L_DEBUG, "%s\n", ptr);
// cut the ' 'and '"' int the beginning of the line
while (*ptr == ' ' || *ptr == '"')
{
ptr++;
}
i = 0;
while(*ptr != '\0')
{
if(*ptr == '"')
break;
//PDEBUG(L_DEBUG, "%c, %d\n", *ptr, *ptr);
tmp[i++] = *ptr++;
}
PDEBUG(L_DEBUG, "%s\n", tmp);
break;
}
}
return 1;
/*------------------------------------------------------------------------------------------------------*/
// Implementation of the Telnet class
#include <stdio.h>
#include "telnet.h"
#include "Socket.h"
#define NUM_TERMINALS 2
#define NUM_CODEC 6
//static unsigned long sa = COLOR_WHITE;
#define NUL 0
#define BEL 7
#define BS 8
#define HT 9
#define LF 10
#define VT 11
#define FF 12
#define CR 13
#define SE 240
#define NOP 241
#define DM 242
#define BRK 243
#define IP 244
#define AO 245
#define AYT 246
#define EC 247
#define EL 248
#define GA 249
#define SB 250
#define WILL 251
#define WONT 252
#define DO 253
#define DONT 254
#define IAC 255
typedef void(*LPCODEPROC) (char*);
typedef void(*LPOPTIONPROC) (_verb,_option);
typedef int(*LPDATAPROC) (unsigned char data);
static void ddww_error(_verb verb,_option option);
static void ddww_echo(_verb verb, _option option);
static void ddww_supp(_verb verb,_option option); //Suppress GA
static void ddww_term(_verb verb,_option option); //Subnegotiate terminal type
static int nvt(unsigned char data);
static int ansi(unsigned char data);
static int sbproc_term(unsigned char data);
static void ansi_set_screen_attribute(char* buffer);
static void ansi_set_position(char* buffer);
static void ansi_erase_screen(char* buffer);
static void ansi_move_up(char* buffer);
static void ansi_erase_line(char* buffer);
int option_error(_verb, _option, int, int);
struct codec_t
{
unsigned char cmd;
LPCODEPROC proc;
};
struct codec_t codec[6] = {
{'m', ansi_set_screen_attribute},
{'H', ansi_set_position},
{'K', ansi_erase_line},
{'J', ansi_erase_screen},
{'A', ansi_move_up},
{0, 0}
};
struct
{
char* name;
LPDATAPROC termproc;
} terminal[NUM_TERMINALS] = {
{ "NVT", nvt },
{ "ANSI", ansi }
};
//
// Construction/Destruction
//
//int nvt(unsigned char data);
typedef enum
{
as_normal,
as_esc,
as_esc1
} _ansi_state;
enum
{
SB_TERM_IS = 0,
SB_TERM_SEND = 1
};
char codebuf[256];
unsigned char codeptr;
int term_index = 0;
int telnet_client_init ( const char* host, const int port )
{
initSocket();
if(!create())
{
printf( "Could not create client socket.\n" );
return 0;
}
if(!socketConnect (host,port))
{
printf( "Could not create connect socket.\n" );
return 0;
}
return 1;
}
void yesreply(_verb verb,_option option)
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (verb==verb_do)?WILL:(verb==verb_dont)?WONT:(verb==verb_will)?DO:DONT;
buf[2] = (unsigned char)option;
socketSend((char*)buf,3);
}
void noreply(_verb verb,_option option)
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (verb==verb_do)?WONT:(verb == verb_dont)?WILL : (verb == verb_will)?DONT:DO;
buf[2] = (unsigned char)option;
socketSend((char*)buf,3);
}
void askfor(_verb verb,_option option)
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (unsigned char)verb;
buf[2] = (unsigned char)option;
socketSend((char*)buf, 3);
}
static void ddww_error(_verb verb, _option option)
{
switch(verb)
{
case verb_will:
noreply(verb,option);
break;
case verb_wont:
return;
case verb_do:
noreply(verb,option);
break;
case verb_dont:
return;
}
}
static void ddww_echo(_verb verb, _option option)
{
int mode;
int set = !(mode & 0xFF);
switch(verb)
{
case verb_will: // server wants to echo stuff
if(set) return; //don't confirm - already set.
break;
case verb_wont: // server don't want to echo
if(!set) return; //don't confirm - already unset.
break;
case verb_do: // server wants me to loopback
noreply(verb,option);
return;
case verb_dont: // server doesn't want me to echo
break; // don't bother to reply - I don't
}
yesreply(verb, option);
}
static void ddww_supp(_verb verb, _option option) //Suppress GA
{
unsigned long mode;
int set = !(mode & 0xFF);
switch(verb)
{
case verb_will: // server wants to suppress GA's
if(set) break; //don't confirm - already set.
askfor(verb_do,TOPT_SUPP);
askfor(verb_will,TOPT_SUPP);
askfor(verb_do,TOPT_ECHO);
break;
case verb_wont: // server wants to send GA's
if(!set) break; //don't confirm - already unset.
askfor(verb_dont,TOPT_SUPP);
askfor(verb_wont,TOPT_SUPP);
break;
case verb_do: // server wants me to suppress GA's
if(set) break;
askfor(verb_do,TOPT_SUPP);
break;
case verb_dont: // server wants me to send GA's
if(!set) break;
askfor(verb_dont,TOPT_SUPP);
break;
}
}
///
// Option TERMINAL-TYPE
static void ddww_term(_verb verb, _option option) //Subnegotiate terminal type
{
switch(verb)
{
case verb_will:
noreply(verb, option); // I don't want terminal info
break;
case verb_wont:
break;
case verb_do:
yesreply(verb, option); //I'll send it when asked
break;
case verb_dont://Ok - I won't
break;
}
}
void termreply(unsigned char data)
{
if(data == SB_TERM_SEND)
{
if(term_index == NUM_TERMINALS)
term_index = 0;
else
term_index++;
char buf[16]; //pls limit
buf[0] = IAC;
buf[1] = SB;
buf[2] = TOPT_TERM;
buf[3] = SB_TERM_IS;
strcpy(&buf[4],terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].name);
int nlen = strlen(&buf[4]);
buf[4+nlen] = IAC;
buf[5+nlen] = SE;
socketSend(buf,4+nlen+2);
}
}
static int sbproc_term(unsigned char data)
{
termreply(data);
return 0;
}
///
struct
{
_option option;
LPOPTIONPROC OptionProc;
LPDATAPROC DataProc;
} ol[] = {
{TOPT_ECHO, ddww_echo, NULL},
{TOPT_SUPP, ddww_supp, NULL},
{TOPT_TERM, ddww_term, sbproc_term},
{TOPT_ERROR, ddww_error, NULL}
};
LPDATAPROC DataProc;
int TelentProtcol(unsigned char code)
{
static int state = state_data;
static _verb verb = verb_sb;
int i;
DataProc = terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].termproc;;
switch(state)
{
case state_data:
switch(code)
{
case IAC: state = state_code; break;
default: return DataProc(code);
}
break;
case state_code:
state = state_data;
switch(code)
{
// State transition back to data
case NOP:
case DM:
case BRK:
case IP:
case AO:
case AYT:
case EC:
case EL:
case GA:
break;
case IAC:
DataProc(code);
break;
// Code state transitions back to data
case SE:
DataProc = terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].termproc;
break;
// Transitions to option state
case SB:
verb = verb_sb;
state = state_option;
break;
case WILL:
verb = verb_will;
state = state_option;
break;
case WONT:
verb = verb_wont;
state = state_option;
break;
case DO:
verb = verb_do;
state = state_option;
break;
case DONT:
verb = verb_dont;
state = state_option;
break;
}
break;
case state_option:
state = state_data;
//Find the option entry
for(
i = 0;
ol[i].option != TOPT_ERROR && ol[i].option != code;
i++);
//Do some verb specific stuff
if(verb == verb_sb)
DataProc = ol[i].DataProc;
else
ol[i].OptionProc(verb,(_option)code);
break;
}
return 0;
}
static int nvt(unsigned char data)
{
if(0 == data)
{
return 0;
}
return 1;
}
static void ansi_set_screen_attribute(char* buffer)
{
while(*buffer)
{
switch(*buffer++)
{
case '0': //Normal
case '1': //Hign Intensity
case '4': //Underscore
case '5': //Blink.
case '7':
case '8':
break;
case '3':
if(*buffer)
buffer++;
break;
case '6':
if(*buffer)
buffer++;
break;
}
if(*buffer && *buffer == ';')
buffer++;
}
}
static void ansi_erase_line(char* buffer)
{
int act = 0;
while(*buffer)
{
act = (*buffer++) - '0';
}
}
static void ansi_set_position(char* buffer)
{
// Grab line
while(*buffer && *buffer != ';')
buffer++;
if(*buffer)
buffer++;
// Grab y
while(*buffer && *buffer != ';')
buffer++;
}
static void ansi_erase_screen(char* buffer)
{
int act = 0;
while(*buffer)
{
act = (*buffer++) - '0';
}
}
static void ansi_move_up(char* buffer)
{
int cnt = *buffer?0:1;
while(*buffer)
{
cnt = cnt*10 + (*buffer++) - '0';
}
}
static int ansi(unsigned char data)
{
int i;
static _ansi_state state = as_normal;
switch( state)
{
case as_normal:
switch(data)
{
case 0: //eat null codes.
break;
case 27: //ANSI esc.
state = as_esc;
break;
default: //Send all else to the console.
return 1;
}
break;
case as_esc:
state = as_esc1;
codeptr = 0;
codebuf[codeptr] = 0;
break;
case as_esc1:
if(data > 64)
{
codebuf[codeptr] = 0;
for(i=0; codec[i].cmd && codec[i].cmd != data; i++);
if(codec[i].proc)
codec[i].proc(codebuf);
state = as_normal;
}
else
codebuf[codeptr++] = data;
break;
}
return 0;
}
int TelnetSend( const char* s )
{
if(!socketSend(s, strlen(s)))
{
printf( "Could not write to socket.\n" );
return 0;
}
return 1;
}
int TelnetRecv(char* s )
{
char buf[40960 + 1];
char *sPtr=buf;
int iRet,i=0;
int ret;
memset(buf,0,sizeof(buf));
iRet = socketRecv(buf);
ret = iRet;
if (iRet < 0)
{
printf ("TelnetRecv socket error.\n");
return iRet;
}
while(iRet--)
{
if(TelentProtcol(*sPtr))
{
buf[i]=*sPtr;
i++;
}
sPtr++;
}
buf[i]=0;
strncpy(s, buf, 4096);
return ret;
}
/*--------------------------------------------------------------------------------------------*/
#include "Socket.h"
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
int m_sock_fd = -1;
struct sockaddr_in m_addr;
int is_valid()
{
return m_sock_fd != -1;
}
int initSocket()
{
memset (&m_addr, 0, sizeof(m_addr));
return 1;
}
void sock_client_free()
{
shutdown(m_sock_fd,SHUT_RDWR);
close ( m_sock_fd );
m_sock_fd=-1;
}
int create()
{
int on = 1;
m_sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (!is_valid())
return 0;
if (setsockopt(m_sock_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof (on)) == -1)
return 0;
return 1;
}
int socketConnect(const char* host, const int port)
{
int ret;
int status;
struct timeval timeout={0, 300000};//3s
if (!is_valid())
return 0;
m_addr.sin_family = AF_INET;
m_addr.sin_port = htons (port);
status = inet_pton (AF_INET, host, &m_addr.sin_addr);
if(errno == EAFNOSUPPORT)
return 0;
ret = setsockopt(m_sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
if(-1 == ret)
{
PDEBUG(L_CRIT, "setsockopt is error!\n");
}
status = connect(m_sock_fd, (struct m_addr *)&m_addr, sizeof(m_addr));
if (status != 0)
{
PDEBUG(L_CRIT, "socket client connect was failed!\n");
return 0;
}
PDEBUG(L_DEBUG, "socket client connect have been successful!\n");
return 1;
}
int socketSend(const void *buf, size_t len)
{
int status;
status = send(m_sock_fd, buf, len, MSG_NOSIGNAL);
if (status == -1 && EAGAIN == errno)
{
return 0;
}
return status;
}
int socketRecv(char *sBuf)
{
memset(sBuf, 0, 40960);
return recv(m_sock_fd, sBuf, 40960, 0);
}
/*-----------------------------command.h--------------------------------------------------------*/
// Definition of the Telnet class
#ifndef __COMMAND_H__
#define __COMMAND_H__
int telnet_command_init(void);
int telnet_send_cmd_mesg(const char * command, char * resp);
int command_init(const char *cmd, char *resp);
int parse_cmd_resp_packet(const char *cmd, const char *key, void *store);
#endif /* __COMMAND_H__ */
/*------------------------------socket.h-------------------------------------------------------------------*/
// Definition of the Socket class
#ifndef Socket_class
#define Socket_class
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "log.h"
int initSocket();
void sock_client_free();
int create();
int socketConnect ( const char* host, const int port );
int socketSend(const void *buf, size_t len) ;
int socketRecv ( char *sBuf ) ;
int is_valid();
#endif
/*--------------------------------telnet.h-----------------------------------------------------------------*/
// Definition of the Telnet class
#ifndef Telnet_class
#define Telnet_class
#include "Socket.h"
typedef enum
{
verb_sb = 250,
verb_will = 251,
verb_wont = 252,
verb_do = 253,
verb_dont = 254
} _verb;
typedef enum
{
state_data, //we expect a data byte
state_code, //we expect a code
state_option //we expect an option
} _state;
typedef enum
{
TOPT_BIN = 0, // Binary Transmission
TOPT_ECHO = 1, // Echo
TOPT_RECN = 2, // Reconnection
TOPT_SUPP = 3, // Suppress Go Ahead
TOPT_APRX = 4, // Approx Message Size Negotiation
TOPT_STAT = 5, // Status
TOPT_TIM = 6, // Timing Mark
TOPT_REM = 7, // Remote Controlled Trans and Echo
TOPT_OLW = 8, // Output Line Width
TOPT_OPS = 9, // Output Page Size
TOPT_OCRD = 10, // Output Carriage-Return Disposition
TOPT_OHT = 11, // Output Horizontal Tabstops
TOPT_OHTD = 12, // Output Horizontal Tab Disposition
TOPT_OFD = 13, // Output Formfeed Disposition
TOPT_OVT = 14, // Output Vertical Tabstops
TOPT_OVTD = 15, // Output Vertical Tab Disposition
TOPT_OLD = 16, // Output Linefeed Disposition
TOPT_EXT = 17, // Extended ASCII
TOPT_LOGO = 18, // Logout
TOPT_BYTE = 19, // Byte Macro
TOPT_DATA = 20, // Data Entry Terminal
TOPT_SUP = 21, // SUPDUP
TOPT_SUPO = 22, // SUPDUP Output
TOPT_SNDL = 23, // Send Location
TOPT_TERM = 24, // Terminal Type
TOPT_EOR = 25, // End of Record
TOPT_TACACS = 26, // TACACS User Identification
TOPT_OM = 27, // Output Marking
TOPT_TLN = 28, // Terminal Location Number
TOPT_3270 = 29, // Telnet 3270 Regime
TOPT_X3 = 30, // X.3 PAD
TOPT_NAWS = 31, // Negotiate About Window Size
TOPT_TS = 32, // Terminal Speed
TOPT_RFC = 33, // Remote Flow Control
TOPT_LINE = 34, // Linemode
TOPT_XDL = 35, // X Display Location
TOPT_ENVIR = 36,// Telnet Environment Option
TOPT_AUTH = 37, // Telnet Authentication Option
TOPT_NENVIR = 39,// Telnet Environment Option
TOPT_EXTOP = 255, // Extended-Options-List
TOPT_ERROR = 256 // Magic number
} _option;
int telnet_client_init ( const char* host,const int port );
int freeTelnet();
int TelnetSend( const char* s ) ;
int TelnetRecv(char* s );
int TelentProtcol(unsigned char code);
#endif
/*-----------------------------------log.c-------------------------------------------*/
#include "log.h"
#include <stdio.h>
#include <stdarg.h>
void log_message(const char *fname, int line, int priority, const char *format, ...)
{
va_list vp;
time_t tv;
struct tm *t;
time (&tv);
t = localtime(&tv);
flockfile(stdout);
va_start(vp, format);
fprintf(stdout, "%d/%d/%d %d:%d:%d[%s: %dL] ",(1900 + t->tm_year), (1 + t->tm_mon), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, fname, line);
vfprintf(stdout, format, vp);
va_end(vp);
funlockfile(stdout);
}
/*-------------------------------------------log.h------------------------------------------------*/
#define LOG_H
#include <time.h>
void log_message(const char *fname, int line, int priority, const char *format, ...);
#define PDEBUG(priority, fmt, args...) log_message(__FILE__, __LINE__, priority, fmt, ##args)
enum {
L_CRIT,
L_WARNING,
L_NOTICE,
L_INFO,
L_DEBUG
};
#endif // LOG_H
/*------------------------------------------------------------------------------------------------------*/
#include "telnet.h"
#include "command.h"
char resultBuf[4096] = {0};
int main(int argc, char *argv[])
{
char *store;
// telnet_command_init();
parse_cmd_resp_packet("show DeviceInfo;", "AdditionalSoftwareVersion", store);
return 0;
}
/*--------------------------command.c---------------------------------------------------*/
#include "telnet.h"
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#define SERVER_IP "192.168.100.111" //板子的IP
#define SERVER_PORT 50000
#define RECV_SIZE 4096
#define SEND_SIZE 2048
int telnet_command_init(void)
{
int ret;
extern int m_sock_fd;
char send_buff[SEND_SIZE] = {0};
char recv_buff[RECV_SIZE] = {0};
while(1)
{
Reconnection:
sock_client_free();
ret = telnet_client_init(SERVER_IP, SERVER_PORT);
if(0 == ret)
{
PDEBUG(L_CRIT, "Telnet client init was failed!\n");
sleep(1);
continue;
}
PDEBUG(L_DEBUG, "Telnet client init was successful!\n");
while(1)
{
strcpy(recv_buff, "");
ret = TelnetRecv(recv_buff);
if(ret < 0)
{
PDEBUG(L_CRIT, "Telnet client recv messages were error!\n");
continue;
}
else if(0 == ret)
{
PDEBUG(L_WARNING, "Telnet link were shutdown by peer server, create telnet link again!\n");
goto Reconnection;
}
PDEBUG(L_DEBUG, "recv buff: %s\n", recv_buff);
if(strstr(recv_buff, "user"))
{
strcat(send_buff, "webroot\r\n");
TelnetSend(send_buff);
continue;
}
if(strstr(recv_buff, "pwd"))
{
strcat(send_buff, "webroot\r\n");
TelnetSend(send_buff);
strcat(send_buff, "show DeviceInfo;");
recv(m_sock_fd, recv_buff, RECV_SIZE, MSG_WAITALL);
return 1;
}
}
}
return 0;
}
int telnet_send_cmd_mesg(const char* command, char* resp)
{
int ret = 0;
extern int m_sock_fd;
char recv_buff[RECV_SIZE] = {0};
char send_buff[SEND_SIZE] = {0};
if(-1 == m_sock_fd)
{
while(1)
{
ret = telnet_command_init();
if(0 == ret)
{
PDEBUG(L_CRIT, "Telnet client init was failed!\n");
sleep(1);
continue;
}
break;
}
}
if(NULL == command)
{
PDEBUG(L_CRIT, "Telnet command was NULL, please confirm the command is right!\n");
return 0;
}
memset(send_buff, 0, sizeof(send_buff));
strncpy(send_buff, command, sizeof(send_buff));
strncat(send_buff, "\r\n", sizeof(send_buff));
ret = send(m_sock_fd, send_buff, strlen(send_buff), MSG_NOSIGNAL);
if(ret < 0)
{
PDEBUG(L_WARNING, "Socket client send messages was failed, convert telnet type to send message continue!\n");
if(m_sock_fd < 0)
{
while(1)
{
if(!telnet_command_init())
{
PDEBUG(L_CRIT, "Telnet client init was failed!\n");
sleep(1);
continue;
}
break;
}
}
ret = TelnetSend(send_buff);
if(0 == ret)
{
PDEBUG(L_CRIT, "Telnet client send message were failed!\n");
return 0;
}
}
while(1)
{
ret = recv(m_sock_fd, recv_buff, RECV_SIZE, MSG_WAITALL);
// PDEBUG(L_DEBUG, "recv messages: %s\n", recv_buff);
if(-1 == ret && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK ||errno==2))
continue;
if(0 == ret)
{
PDEBUG(L_WARNING, "the connect were shutdown by peer server!\n");
if(0 == telnet_command_init())
{
PDEBUG(L_CRIT, "telnet command init was failed!\n");
return 0;
}
ret = send(m_sock_fd, send_buff, strlen(send_buff), 0);
if(ret < 0)
{
PDEBUG(L_WARNING, "Socket client send messages was failed, convert telnet type to send message continue!\n");
ret = TelnetSend(send_buff);
if(0 == ret)
{
PDEBUG(L_CRIT, "telnet send messages were failed!\n");
return 0;
}
continue;
}
}
else if(ret < 0)
{
PDEBUG(L_WARNING, "Socket client recv messages was failed, continue recv ...\n");
continue;
}
if(NULL != strstr(recv_buff, "#"))
{
strncpy(resp, recv_buff, RECV_SIZE);
break;
}
continue;
}
return 1;
}
int command_init(const char *cmd, char *resp)
{
int ret;
ret = telnet_command_init();
if(0 == ret)
{
PDEBUG(L_CRIT, "telnet_command_init was failed!\n");
return 0;
}
ret = telnet_send_cmd_mesg(cmd, resp);
if(0 == ret)
{
PDEBUG(L_CRIT, "telnet_send_cmd_mesg was failed!\n");
return 0;
}
return 1;
}
int parse_cmd_resp_packet(const char *cmd, const char *key, void *store)
{
int ret;
int i;
char *substr, *ptr;
char tmp[RECV_SIZE] = {0};
char rcv_buf[RECV_SIZE] = {0};
ret = telnet_send_cmd_mesg(cmd, rcv_buf);
if(0 == ret)
{
PDEBUG(L_CRIT, "telnet send command was failed!\n");
return 0;
}
PDEBUG(L_DEBUG, "recv buff: %s\n", rcv_buf);
//the rcv messages were by divided "\r\n", if there are n num"\r\n", there are (n + 1) partions;
substr = strtok(rcv_buf, "\r\n");
if(NULL == substr)
{
PDEBUG(L_CRIT, "Not found the sub string!\n");
return 0;
}
//decide the respond messages by the first line;
ptr = strstr(substr, "error");
if(ptr)
{
PDEBUG(L_CRIT, "the respond messages were error!\n");
return 0;
}
// the substr pointed to each line;
while(substr)
{
substr = strtok(NULL, "\r\n");
ptr = strstr(substr, key);
if(ptr)
{
PDEBUG(L_DEBUG, "%s\n", substr);
ptr = strtok(substr, "=");
if(NULL == ptr)
{
PDEBUG(L_CRIT, "Not found the sub string!\n");
return 0;
}
ptr = strtok(NULL, "=");
if(NULL == ptr)
{
PDEBUG(L_CRIT, "Not found the sub string!\n");
return 0;
}
PDEBUG(L_DEBUG, "%s\n", ptr);
// cut the ' 'and '"' int the beginning of the line
while (*ptr == ' ' || *ptr == '"')
{
ptr++;
}
i = 0;
while(*ptr != '\0')
{
if(*ptr == '"')
break;
//PDEBUG(L_DEBUG, "%c, %d\n", *ptr, *ptr);
tmp[i++] = *ptr++;
}
PDEBUG(L_DEBUG, "%s\n", tmp);
break;
}
}
return 1;
/*------------------------------------------------------------------------------------------------------*/
// Implementation of the Telnet class
#include <stdio.h>
#include "telnet.h"
#include "Socket.h"
#define NUM_TERMINALS 2
#define NUM_CODEC 6
//static unsigned long sa = COLOR_WHITE;
#define NUL 0
#define BEL 7
#define BS 8
#define HT 9
#define LF 10
#define VT 11
#define FF 12
#define CR 13
#define SE 240
#define NOP 241
#define DM 242
#define BRK 243
#define IP 244
#define AO 245
#define AYT 246
#define EC 247
#define EL 248
#define GA 249
#define SB 250
#define WILL 251
#define WONT 252
#define DO 253
#define DONT 254
#define IAC 255
typedef void(*LPCODEPROC) (char*);
typedef void(*LPOPTIONPROC) (_verb,_option);
typedef int(*LPDATAPROC) (unsigned char data);
static void ddww_error(_verb verb,_option option);
static void ddww_echo(_verb verb, _option option);
static void ddww_supp(_verb verb,_option option); //Suppress GA
static void ddww_term(_verb verb,_option option); //Subnegotiate terminal type
static int nvt(unsigned char data);
static int ansi(unsigned char data);
static int sbproc_term(unsigned char data);
static void ansi_set_screen_attribute(char* buffer);
static void ansi_set_position(char* buffer);
static void ansi_erase_screen(char* buffer);
static void ansi_move_up(char* buffer);
static void ansi_erase_line(char* buffer);
int option_error(_verb, _option, int, int);
struct codec_t
{
unsigned char cmd;
LPCODEPROC proc;
};
struct codec_t codec[6] = {
{'m', ansi_set_screen_attribute},
{'H', ansi_set_position},
{'K', ansi_erase_line},
{'J', ansi_erase_screen},
{'A', ansi_move_up},
{0, 0}
};
struct
{
char* name;
LPDATAPROC termproc;
} terminal[NUM_TERMINALS] = {
{ "NVT", nvt },
{ "ANSI", ansi }
};
//
// Construction/Destruction
//
//int nvt(unsigned char data);
typedef enum
{
as_normal,
as_esc,
as_esc1
} _ansi_state;
enum
{
SB_TERM_IS = 0,
SB_TERM_SEND = 1
};
char codebuf[256];
unsigned char codeptr;
int term_index = 0;
int telnet_client_init ( const char* host, const int port )
{
initSocket();
if(!create())
{
printf( "Could not create client socket.\n" );
return 0;
}
if(!socketConnect (host,port))
{
printf( "Could not create connect socket.\n" );
return 0;
}
return 1;
}
void yesreply(_verb verb,_option option)
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (verb==verb_do)?WILL:(verb==verb_dont)?WONT:(verb==verb_will)?DO:DONT;
buf[2] = (unsigned char)option;
socketSend((char*)buf,3);
}
void noreply(_verb verb,_option option)
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (verb==verb_do)?WONT:(verb == verb_dont)?WILL : (verb == verb_will)?DONT:DO;
buf[2] = (unsigned char)option;
socketSend((char*)buf,3);
}
void askfor(_verb verb,_option option)
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (unsigned char)verb;
buf[2] = (unsigned char)option;
socketSend((char*)buf, 3);
}
static void ddww_error(_verb verb, _option option)
{
switch(verb)
{
case verb_will:
noreply(verb,option);
break;
case verb_wont:
return;
case verb_do:
noreply(verb,option);
break;
case verb_dont:
return;
}
}
static void ddww_echo(_verb verb, _option option)
{
int mode;
int set = !(mode & 0xFF);
switch(verb)
{
case verb_will: // server wants to echo stuff
if(set) return; //don't confirm - already set.
break;
case verb_wont: // server don't want to echo
if(!set) return; //don't confirm - already unset.
break;
case verb_do: // server wants me to loopback
noreply(verb,option);
return;
case verb_dont: // server doesn't want me to echo
break; // don't bother to reply - I don't
}
yesreply(verb, option);
}
static void ddww_supp(_verb verb, _option option) //Suppress GA
{
unsigned long mode;
int set = !(mode & 0xFF);
switch(verb)
{
case verb_will: // server wants to suppress GA's
if(set) break; //don't confirm - already set.
askfor(verb_do,TOPT_SUPP);
askfor(verb_will,TOPT_SUPP);
askfor(verb_do,TOPT_ECHO);
break;
case verb_wont: // server wants to send GA's
if(!set) break; //don't confirm - already unset.
askfor(verb_dont,TOPT_SUPP);
askfor(verb_wont,TOPT_SUPP);
break;
case verb_do: // server wants me to suppress GA's
if(set) break;
askfor(verb_do,TOPT_SUPP);
break;
case verb_dont: // server wants me to send GA's
if(!set) break;
askfor(verb_dont,TOPT_SUPP);
break;
}
}
///
// Option TERMINAL-TYPE
static void ddww_term(_verb verb, _option option) //Subnegotiate terminal type
{
switch(verb)
{
case verb_will:
noreply(verb, option); // I don't want terminal info
break;
case verb_wont:
break;
case verb_do:
yesreply(verb, option); //I'll send it when asked
break;
case verb_dont://Ok - I won't
break;
}
}
void termreply(unsigned char data)
{
if(data == SB_TERM_SEND)
{
if(term_index == NUM_TERMINALS)
term_index = 0;
else
term_index++;
char buf[16]; //pls limit
buf[0] = IAC;
buf[1] = SB;
buf[2] = TOPT_TERM;
buf[3] = SB_TERM_IS;
strcpy(&buf[4],terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].name);
int nlen = strlen(&buf[4]);
buf[4+nlen] = IAC;
buf[5+nlen] = SE;
socketSend(buf,4+nlen+2);
}
}
static int sbproc_term(unsigned char data)
{
termreply(data);
return 0;
}
///
struct
{
_option option;
LPOPTIONPROC OptionProc;
LPDATAPROC DataProc;
} ol[] = {
{TOPT_ECHO, ddww_echo, NULL},
{TOPT_SUPP, ddww_supp, NULL},
{TOPT_TERM, ddww_term, sbproc_term},
{TOPT_ERROR, ddww_error, NULL}
};
LPDATAPROC DataProc;
int TelentProtcol(unsigned char code)
{
static int state = state_data;
static _verb verb = verb_sb;
int i;
DataProc = terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].termproc;;
switch(state)
{
case state_data:
switch(code)
{
case IAC: state = state_code; break;
default: return DataProc(code);
}
break;
case state_code:
state = state_data;
switch(code)
{
// State transition back to data
case NOP:
case DM:
case BRK:
case IP:
case AO:
case AYT:
case EC:
case EL:
case GA:
break;
case IAC:
DataProc(code);
break;
// Code state transitions back to data
case SE:
DataProc = terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].termproc;
break;
// Transitions to option state
case SB:
verb = verb_sb;
state = state_option;
break;
case WILL:
verb = verb_will;
state = state_option;
break;
case WONT:
verb = verb_wont;
state = state_option;
break;
case DO:
verb = verb_do;
state = state_option;
break;
case DONT:
verb = verb_dont;
state = state_option;
break;
}
break;
case state_option:
state = state_data;
//Find the option entry
for(
i = 0;
ol[i].option != TOPT_ERROR && ol[i].option != code;
i++);
//Do some verb specific stuff
if(verb == verb_sb)
DataProc = ol[i].DataProc;
else
ol[i].OptionProc(verb,(_option)code);
break;
}
return 0;
}
static int nvt(unsigned char data)
{
if(0 == data)
{
return 0;
}
return 1;
}
static void ansi_set_screen_attribute(char* buffer)
{
while(*buffer)
{
switch(*buffer++)
{
case '0': //Normal
case '1': //Hign Intensity
case '4': //Underscore
case '5': //Blink.
case '7':
case '8':
break;
case '3':
if(*buffer)
buffer++;
break;
case '6':
if(*buffer)
buffer++;
break;
}
if(*buffer && *buffer == ';')
buffer++;
}
}
static void ansi_erase_line(char* buffer)
{
int act = 0;
while(*buffer)
{
act = (*buffer++) - '0';
}
}
static void ansi_set_position(char* buffer)
{
// Grab line
while(*buffer && *buffer != ';')
buffer++;
if(*buffer)
buffer++;
// Grab y
while(*buffer && *buffer != ';')
buffer++;
}
static void ansi_erase_screen(char* buffer)
{
int act = 0;
while(*buffer)
{
act = (*buffer++) - '0';
}
}
static void ansi_move_up(char* buffer)
{
int cnt = *buffer?0:1;
while(*buffer)
{
cnt = cnt*10 + (*buffer++) - '0';
}
}
static int ansi(unsigned char data)
{
int i;
static _ansi_state state = as_normal;
switch( state)
{
case as_normal:
switch(data)
{
case 0: //eat null codes.
break;
case 27: //ANSI esc.
state = as_esc;
break;
default: //Send all else to the console.
return 1;
}
break;
case as_esc:
state = as_esc1;
codeptr = 0;
codebuf[codeptr] = 0;
break;
case as_esc1:
if(data > 64)
{
codebuf[codeptr] = 0;
for(i=0; codec[i].cmd && codec[i].cmd != data; i++);
if(codec[i].proc)
codec[i].proc(codebuf);
state = as_normal;
}
else
codebuf[codeptr++] = data;
break;
}
return 0;
}
int TelnetSend( const char* s )
{
if(!socketSend(s, strlen(s)))
{
printf( "Could not write to socket.\n" );
return 0;
}
return 1;
}
int TelnetRecv(char* s )
{
char buf[40960 + 1];
char *sPtr=buf;
int iRet,i=0;
int ret;
memset(buf,0,sizeof(buf));
iRet = socketRecv(buf);
ret = iRet;
if (iRet < 0)
{
printf ("TelnetRecv socket error.\n");
return iRet;
}
while(iRet--)
{
if(TelentProtcol(*sPtr))
{
buf[i]=*sPtr;
i++;
}
sPtr++;
}
buf[i]=0;
strncpy(s, buf, 4096);
return ret;
}
/*--------------------------------------------------------------------------------------------*/
#include "Socket.h"
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
int m_sock_fd = -1;
struct sockaddr_in m_addr;
int is_valid()
{
return m_sock_fd != -1;
}
int initSocket()
{
memset (&m_addr, 0, sizeof(m_addr));
return 1;
}
void sock_client_free()
{
shutdown(m_sock_fd,SHUT_RDWR);
close ( m_sock_fd );
m_sock_fd=-1;
}
int create()
{
int on = 1;
m_sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (!is_valid())
return 0;
if (setsockopt(m_sock_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof (on)) == -1)
return 0;
return 1;
}
int socketConnect(const char* host, const int port)
{
int ret;
int status;
struct timeval timeout={0, 300000};//3s
if (!is_valid())
return 0;
m_addr.sin_family = AF_INET;
m_addr.sin_port = htons (port);
status = inet_pton (AF_INET, host, &m_addr.sin_addr);
if(errno == EAFNOSUPPORT)
return 0;
ret = setsockopt(m_sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
if(-1 == ret)
{
PDEBUG(L_CRIT, "setsockopt is error!\n");
}
status = connect(m_sock_fd, (struct m_addr *)&m_addr, sizeof(m_addr));
if (status != 0)
{
PDEBUG(L_CRIT, "socket client connect was failed!\n");
return 0;
}
PDEBUG(L_DEBUG, "socket client connect have been successful!\n");
return 1;
}
int socketSend(const void *buf, size_t len)
{
int status;
status = send(m_sock_fd, buf, len, MSG_NOSIGNAL);
if (status == -1 && EAGAIN == errno)
{
return 0;
}
return status;
}
int socketRecv(char *sBuf)
{
memset(sBuf, 0, 40960);
return recv(m_sock_fd, sBuf, 40960, 0);
}
/*-----------------------------command.h--------------------------------------------------------*/
// Definition of the Telnet class
#ifndef __COMMAND_H__
#define __COMMAND_H__
int telnet_command_init(void);
int telnet_send_cmd_mesg(const char * command, char * resp);
int command_init(const char *cmd, char *resp);
int parse_cmd_resp_packet(const char *cmd, const char *key, void *store);
#endif /* __COMMAND_H__ */
/*------------------------------socket.h-------------------------------------------------------------------*/
// Definition of the Socket class
#ifndef Socket_class
#define Socket_class
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "log.h"
int initSocket();
void sock_client_free();
int create();
int socketConnect ( const char* host, const int port );
int socketSend(const void *buf, size_t len) ;
int socketRecv ( char *sBuf ) ;
int is_valid();
#endif
/*--------------------------------telnet.h-----------------------------------------------------------------*/
// Definition of the Telnet class
#ifndef Telnet_class
#define Telnet_class
#include "Socket.h"
typedef enum
{
verb_sb = 250,
verb_will = 251,
verb_wont = 252,
verb_do = 253,
verb_dont = 254
} _verb;
typedef enum
{
state_data, //we expect a data byte
state_code, //we expect a code
state_option //we expect an option
} _state;
typedef enum
{
TOPT_BIN = 0, // Binary Transmission
TOPT_ECHO = 1, // Echo
TOPT_RECN = 2, // Reconnection
TOPT_SUPP = 3, // Suppress Go Ahead
TOPT_APRX = 4, // Approx Message Size Negotiation
TOPT_STAT = 5, // Status
TOPT_TIM = 6, // Timing Mark
TOPT_REM = 7, // Remote Controlled Trans and Echo
TOPT_OLW = 8, // Output Line Width
TOPT_OPS = 9, // Output Page Size
TOPT_OCRD = 10, // Output Carriage-Return Disposition
TOPT_OHT = 11, // Output Horizontal Tabstops
TOPT_OHTD = 12, // Output Horizontal Tab Disposition
TOPT_OFD = 13, // Output Formfeed Disposition
TOPT_OVT = 14, // Output Vertical Tabstops
TOPT_OVTD = 15, // Output Vertical Tab Disposition
TOPT_OLD = 16, // Output Linefeed Disposition
TOPT_EXT = 17, // Extended ASCII
TOPT_LOGO = 18, // Logout
TOPT_BYTE = 19, // Byte Macro
TOPT_DATA = 20, // Data Entry Terminal
TOPT_SUP = 21, // SUPDUP
TOPT_SUPO = 22, // SUPDUP Output
TOPT_SNDL = 23, // Send Location
TOPT_TERM = 24, // Terminal Type
TOPT_EOR = 25, // End of Record
TOPT_TACACS = 26, // TACACS User Identification
TOPT_OM = 27, // Output Marking
TOPT_TLN = 28, // Terminal Location Number
TOPT_3270 = 29, // Telnet 3270 Regime
TOPT_X3 = 30, // X.3 PAD
TOPT_NAWS = 31, // Negotiate About Window Size
TOPT_TS = 32, // Terminal Speed
TOPT_RFC = 33, // Remote Flow Control
TOPT_LINE = 34, // Linemode
TOPT_XDL = 35, // X Display Location
TOPT_ENVIR = 36,// Telnet Environment Option
TOPT_AUTH = 37, // Telnet Authentication Option
TOPT_NENVIR = 39,// Telnet Environment Option
TOPT_EXTOP = 255, // Extended-Options-List
TOPT_ERROR = 256 // Magic number
} _option;
int telnet_client_init ( const char* host,const int port );
int freeTelnet();
int TelnetSend( const char* s ) ;
int TelnetRecv(char* s );
int TelentProtcol(unsigned char code);
#endif
/*-----------------------------------log.c-------------------------------------------*/
#include "log.h"
#include <stdio.h>
#include <stdarg.h>
void log_message(const char *fname, int line, int priority, const char *format, ...)
{
va_list vp;
time_t tv;
struct tm *t;
time (&tv);
t = localtime(&tv);
flockfile(stdout);
va_start(vp, format);
fprintf(stdout, "%d/%d/%d %d:%d:%d[%s: %dL] ",(1900 + t->tm_year), (1 + t->tm_mon), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, fname, line);
vfprintf(stdout, format, vp);
va_end(vp);
funlockfile(stdout);
}
/*-------------------------------------------log.h------------------------------------------------*/
#define LOG_H
#include <time.h>
void log_message(const char *fname, int line, int priority, const char *format, ...);
#define PDEBUG(priority, fmt, args...) log_message(__FILE__, __LINE__, priority, fmt, ##args)
enum {
L_CRIT,
L_WARNING,
L_NOTICE,
L_INFO,
L_DEBUG
};
#endif // LOG_H
/*------------------------------------------------------------------------------------------------------*/