Преглед изворни кода

[telnet_server]1)add IP option for LINEMODE
2)fix "sensor info" cmd
3)fix "user passwd" cmd

balbekova пре 6 година
родитељ
комит
2103c64137
2 измењених фајлова са 165 додато и 43 уклоњено
  1. 165 23
      modules/Telnet_Server/telnet_server.c
  2. 0 20
      modules/Telnet_Server/telnet_server.h

+ 165 - 23
modules/Telnet_Server/telnet_server.c

@@ -85,21 +85,95 @@
 #define TELOPT_TERMINAL_SPEED      32  // Terminal Speed (RFC1079)
 #define TELOPT_TOGGLE_FLOW_CONTROL 33  // Remote Flow Control (RFC1372)
 #define TELOPT_LINEMODE            34  // Linemode (RFC1184)
+#define TELOPT_DISPLAY_POS         35  // Linemode (RFC1184)
 #define TELOPT_AUTHENTICATION      37  // Authentication (RFC1416)
-
+#define TELOPT_NEW_ENV_OPTION      39  // Authentication (RFC1416)
+
+//Sub option for LINEMODE
+
+#define LINEMODE_MODE             1
+#define LINEMODE_EDIT             1
+#define LINEMODE_TRAPSIG          2
+#define LINEMODE_MODE_ACK         4
+#define LINEMODE_SOFT_TAB         8
+#define LINEMODE_LIT_ECHO        16
+#define LINEMODE_FORWARDMASK      2
+#define LINEMODE_SLC              3
+#define LINEMODE_SLC_SYNCH        1
+#define LINEMODE_SLC_BRK          2
+#define LINEMODE_SLC_IP           3
+#define LINEMODE_SLC_AO           4
+#define LINEMODE_SLC_AYT          5
+#define LINEMODE_SLC_EOR          6
+#define LINEMODE_SLC_ABORT        7
+#define LINEMODE_SLC_EOF          8
+#define LINEMODE_SLC_SUSP         9
+#define LINEMODE_SLC_EC          10
+#define LINEMODE_SLC_EL          11
+#define LINEMODE_SLC_EW          12
+#define LINEMODE_SLC_RP          13
+#define LINEMODE_SLC_LNEXT       14
+#define LINEMODE_SLC_XON         15
+#define LINEMODE_SLC_XOFF        16
+#define LINEMODE_SLC_FORW1       17
+#define LINEMODE_SLC_FORW2       18
+#define LINEMODE_SLC_MCL         19
+#define LINEMODE_SLC_MCR         20
+#define LINEMODE_SLC_MCWL        21
+#define LINEMODE_SLC_MCWR        22
+#define LINEMODE_SLC_MCBOL       23
+#define LINEMODE_SLC_MCEOL       24
+#define LINEMODE_SLC_INSRT       25
+#define LINEMODE_SLC_OVER        26
+#define LINEMODE_SLC_ECR         27
+#define LINEMODE_SLC_EWR         28
+#define LINEMODE_SLC_EBOL        29
+#define LINEMODE_SLC_EEOL        30
+
+#define LINEMODE_SLC_DEFAULT      3
+#define LINEMODE_SLC_VALUE        2
+#define LINEMODE_SLC_CANTCHANGE   1
+#define LINEMODE_SLC_NOSUPPORT    0
+#define LINEMODE_SLC_LEVELBITS    3
+
+#define LINEMODE_SLC_ACK        128
+#define LINEMODE_SLC_FLUSHIN     64
+#define LINEMODE_SLC_FLUSHOUT    32
+#define LINEMODE_EOF            236
+#define LINEMODE_SUSP           237
+#define LINEMODE_ABORT          238
 
 /* Repeat Login timeout, 1 seconds */
-#define REPEAT_SENSOR_INFO_TIME		configTICK_RATE_HZ*1*1
+#define REPEAT_SENSOR_INFO_TIME		configTICK_RATE_HZ*5*1
 
 /* Set option to drop old connection if the new one is accepted */
 #define TCP_DROP_PREV_CONNECTION    0
 
+/**
+ * A telnet connection structure.
+ */
+typedef struct{
+	TimerHandle_t RepeatSensorInfoTimer;
+	uint8_t state;
+	uint8_t code;
+	char buf[cmdMAX_INPUT_SIZE];
+	char bufptr;
+	char prev_cmd[cmdMAX_INPUT_SIZE];
+	unsigned char optdata[cmdMAX_INPUT_SIZE];
+	uint8_t optlen;
+	state_telnet_server_t telnetState;
+	user_level_t telnet_code_auth;
+	char login[MAX_WEB_LOGIN_LEN];
+	uint8_t login_err;
+	uint8_t num_connect;
+	bool active_conn;
+	bool flagWhiteListTelnet;
+}telnetd_state_t;
+
 static portBASE_TYPE FreeRTOS_CLIAuthProcess( int8_t * pcWriteBuffer, telnetd_state_t *s  );
 static portBASE_TYPE FreeRTOS_ChangePWDProcess( int8_t * pcWriteBuffer, telnetd_state_t *s  );
 void SensorInfoTimerCallback(TimerHandle_t pxTimer);
 
-TimerHandle_t RepeatSensorInfoTimer;
-
 state_telnet_server_t telnetState = TELNET_AUTH;
 uint8_t id_change_pwd = 0;
 user_level_t telnet_code_auth = USER;
@@ -192,6 +266,7 @@ static void telnetd_input(telnetd_state_t *s)
 					/* Ensure there is not a string lingering in
 					the output buffer. */
 					pcOutputString[ 0 ] = 0x00;
+					telnetState = s->telnetState;
 					xReturned = FreeRTOS_CLIProcessCommand( s->buf, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
 					s->telnetState = telnetState;
 					send( s->num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
@@ -201,7 +276,7 @@ static void telnetd_input(telnetd_state_t *s)
 				if( strcmp( "sensor info", ( const char * ) s->buf ) == 0 ){
 					strcpy( s->prev_cmd, s->buf );
 					memset( s->buf, 0x00, cmdMAX_INPUT_SIZE );
-					xTimerStart(RepeatSensorInfoTimer, 0);
+					xTimerStart(s->RepeatSensorInfoTimer, 0);
 				}
 				else{
 
@@ -230,9 +305,12 @@ static void telnetd_input(telnetd_state_t *s)
 /*-----------------------------------------------------------------------------------*/
 static void getchar(telnetd_state_t *s)
 {
-	if(type_term == 1){
+	if(type_term == 1 && s->telnetState != TELNET_AUTH_PASSW){
 		send( s->num_connect, &s->buf[s->bufptr], 1, 0 );
 	}
+	else if(s->telnetState == TELNET_AUTH_PASSW){
+		send( s->num_connect, " ", 1, 0 );
+	}
 
 
   if(s->buf[s->bufptr] == ISO_nl ||
@@ -273,6 +351,18 @@ static void sendopt(telnetd_state_t *s, u8_t code, u8_t option)
     send( s->num_connect, buf, 3, 0 );
 }
 
+static void sendsubopt(telnetd_state_t *s, u8_t code, u8_t *option, u8_t len)
+{
+	unsigned char buf[cmdMAX_INPUT_SIZE+3];
+	buf[0] = TELNET_IAC;
+	buf[1] = TELNET_SB;
+	buf[2] = code;
+	memcpy(&buf[3], option, len);
+	buf[len + 3] = TELNET_IAC;
+	buf[len + 4] = TELNET_SE;
+    send( s->num_connect, buf, (len + 5), 0 );
+}
+
 void parseopt(telnetd_state_t *ts, uint8_t code, uint8_t option)
 {
 
@@ -288,11 +378,17 @@ void parseopt(telnetd_state_t *ts, uint8_t code, uint8_t option)
     case TELOPT_SUPPRESS_GO_AHEAD:
     case TELOPT_LINEMODE:
     case TELOPT_NAWS:
+    case TELOPT_DISPLAY_POS:
+    case TELOPT_NEW_ENV_OPTION:
+    case TELOPT_TERMINAL_SPEED:
+    case TELOPT_TERMINAL_TYPE:
+    case TELOPT_STATUS:
+    case TELOPT_TOGGLE_FLOW_CONTROL:
       break;
 
     case TELOPT_TIMING_MARK:
-
-    	xTimerStop(RepeatSensorInfoTimer, 0);
+    	memset(ts->prev_cmd, 0, cmdMAX_INPUT_SIZE );
+    	xTimerStop(ts->RepeatSensorInfoTimer, 0);
 		sendopt(ts, TELNET_WILL, TELOPT_TIMING_MARK);
 		sendopt(ts, TELNET_MARK, 0);
 		if(ts->telnetState != TELNET_CHANGE_PWD && ts->telnetState != TELNET_CHANGE_PWD_ACK)
@@ -311,6 +407,10 @@ void parseopt(telnetd_state_t *ts, uint8_t code, uint8_t option)
 
 static void parseoptdat(telnetd_state_t *ts, int option, unsigned char *data, uint8_t len) {
 
+	uint8_t subopt = 0;
+	uint8_t subopt_val = 0;
+	uint8_t sub_opt_data[2] = {LINEMODE_MODE, LINEMODE_EDIT};
+
   switch (option) {
     case TELOPT_NAWS:
       break;
@@ -320,6 +420,35 @@ static void parseoptdat(telnetd_state_t *ts, int option, unsigned char *data, ui
 
     case TELOPT_TERMINAL_TYPE:
       break;
+    case TELOPT_LINEMODE:
+    	subopt = data[0];
+    	switch (subopt) {
+		case LINEMODE_SLC:
+			if(data[2] & LINEMODE_SLC_ACK){
+				return;
+			}
+			sendsubopt(ts, option, sub_opt_data, 2);
+			for(uint8_t i = 1; i < len; i += 3){
+				subopt_val = data[i];
+				switch (subopt_val) {
+				case LINEMODE_SLC_IP:
+					data[i+1] = LINEMODE_SLC_VALUE | LINEMODE_SLC_FLUSHIN | LINEMODE_SLC_FLUSHOUT | LINEMODE_SLC_ACK;
+					break;
+				case LINEMODE_SLC_XON:
+				case LINEMODE_SLC_XOFF:
+				case LINEMODE_SLC_EC:
+					data[i+1] = LINEMODE_SLC_VALUE | LINEMODE_SLC_ACK;
+					break;
+				default:
+					data[i+1] = LINEMODE_SLC_NOSUPPORT;
+					data[i+2] = 0;
+					break;
+				}
+			}
+			sendsubopt(ts, option, data, len);
+			break;
+    	}
+		break;
   }
 }
 
@@ -365,17 +494,19 @@ static void newdata(telnetd_state_t *s)
 		break;
 
 	case STATE_OPTDAT:
-		if (c == TELNET_IAC) {
-		  s->state = STATE_SE;
+		if (c == TELNET_SE && s->optdata[s->optlen-1] == TELNET_IAC) {
+			parseoptdat(s, s->code, s->optdata, (s->optlen-1));
+			s->state = STATE_NORMAL;
+		  //s->state = STATE_SE;
 		} else if (s->optlen < sizeof(s->optdata)) {
 		  s->optdata[s->optlen++] = c;
 		}
 		break;
 
-	case STATE_SE:
+	/*case STATE_SE:
 		if (c == TELNET_SE) parseoptdat(s, s->code, s->optdata, s->optlen);
 		s->state = STATE_NORMAL;
-		break;
+		break;*/
     case STATE_NORMAL:
       if(c == TELNET_IAC) {
     	  s->state = STATE_IAC;
@@ -602,11 +733,11 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 #endif
 									while(recv( new_sd, &auth_tlnt_srvr_param[k].buf[auth_tlnt_srvr_param[k].bufptr], 1,  MSG_DONTWAIT ) > 0){
 										newdata(&auth_tlnt_srvr_param[k]);
-										vTaskDelay(5);
+										vTaskDelay(10);
 									}
-									sendopt(&auth_tlnt_srvr_param[k], TELNET_WILL, TELOPT_SUPPRESS_GO_AHEAD);
-									sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_ECHO);
+									sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_SUPPRESS_GO_AHEAD);
 									sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_LINEMODE);
+									sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_ECHO);
 									vTaskDelay(50);
 									while(recv( new_sd, &auth_tlnt_srvr_param[k].buf[auth_tlnt_srvr_param[k].bufptr], 1,  MSG_DONTWAIT ) > 0){
 										newdata(&auth_tlnt_srvr_param[k]);
@@ -703,11 +834,16 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 					/* based on the bits that are still turned on in */
 					/* the master set.                               */
 					if (auth_tlnt_srvr_param[cur_cnt].state == STATE_CLOSE) {
+						memset(auth_tlnt_srvr_param[cur_cnt].buf, 0, cmdMAX_INPUT_SIZE);
+						memset(auth_tlnt_srvr_param[cur_cnt].prev_cmd, 0, cmdMAX_INPUT_SIZE);
+						memset(auth_tlnt_srvr_param[cur_cnt].optdata, 0, cmdMAX_INPUT_SIZE);
+						auth_tlnt_srvr_param[cur_cnt].optlen = 0;
 						auth_tlnt_srvr_param[cur_cnt].state = STATE_NORMAL;
 						auth_tlnt_srvr_param[cur_cnt].num_connect = 0;
 						auth_tlnt_srvr_param[cur_cnt].active_conn = false;
 						auth_tlnt_srvr_param[cur_cnt].telnetState = TELNET_AUTH;
 						auth_tlnt_srvr_param[cur_cnt].telnet_code_auth = USER;
+						xTimerStop(auth_tlnt_srvr_param[cur_cnt].RepeatSensorInfoTimer, 0);
 						cnt_conn -= 1;
 						closesocket(i);
 						FD_CLR(i, &master_set);
@@ -725,33 +861,39 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 
 void telnet_server_init(void) {
 	for(uint8_t i = 0; i < NUMBER_TELNET_CONNECT; i++){
+		memset(auth_tlnt_srvr_param[i].buf, 0, cmdMAX_INPUT_SIZE);
+		memset(auth_tlnt_srvr_param[i].prev_cmd, 0, cmdMAX_INPUT_SIZE);
+		memset(auth_tlnt_srvr_param[i].optdata, 0, cmdMAX_INPUT_SIZE);
+		auth_tlnt_srvr_param[i].optlen = 0;
 		auth_tlnt_srvr_param[i].num_connect = 0;
 		auth_tlnt_srvr_param[i].active_conn = false;
 		auth_tlnt_srvr_param[i].telnetState = TELNET_AUTH;
 		auth_tlnt_srvr_param[i].telnet_code_auth = USER;
+		auth_tlnt_srvr_param[i].RepeatSensorInfoTimer = xTimerCreate("SensorInfoTmr", REPEAT_SENSOR_INFO_TIME, pdFALSE, ( void * ) i, SensorInfoTimerCallback);
 	}
 	vRegisterCLICommands();
 	xTaskCreate(vBasicSocketsCommandInterpreterTask, ( char * ) "vBasicSocketsCommandInterpreterTask", 8*configMINIMAL_STACK_SIZE , NULL, tskIDLE_PRIORITY + 1, NULL);
-	 RepeatSensorInfoTimer = xTimerCreate("SensorInfoTmr", REPEAT_SENSOR_INFO_TIME, pdFALSE, ( void * ) 0, SensorInfoTimerCallback);
 }
 
 void SensorInfoTimerCallback(TimerHandle_t pxTimer) {
 	portBASE_TYPE xReturned = pdTRUE;
-
+	uint8_t num_timer;
+	for(uint8_t i = 0; i < NUMBER_TELNET_CONNECT; i ++){
+		if(pxTimer == auth_tlnt_srvr_param[i].RepeatSensorInfoTimer){
+			num_timer = i;
+			break;
+		}
+	}
 	do
 	{
 		/* Ensure there is not a string lingering in
 		the output buffer. */
 		pcOutputString[ 0 ] = 0x00;
 		xReturned = FreeRTOS_CLIProcessCommand( "sensor info", pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
-		for(uint8_t i = 0; i < NUMBER_TELNET_CONNECT; i++){
-			if(auth_tlnt_srvr_param[i].active_conn){
-				lwip_send( auth_tlnt_srvr_param[i].num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
-			}
-		}
+		send( auth_tlnt_srvr_param[num_timer].num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
 
 	} while( xReturned != pdFALSE );
-	xTimerStart(RepeatSensorInfoTimer, 0);
+	xTimerStart(auth_tlnt_srvr_param[num_timer].RepeatSensorInfoTimer, 0);
 }
 
 static portBASE_TYPE FreeRTOS_CLIAuthProcess( int8_t * pcWriteBuffer, telnetd_state_t *s  )

+ 0 - 20
modules/Telnet_Server/telnet_server.h

@@ -24,26 +24,6 @@ typedef enum{
 	TELNET_CHANGE_PWD_ACK
 }state_telnet_server_t;
 
-/**
- * A telnet connection structure.
- */
-typedef struct{
-	uint8_t state;
-	uint8_t code;
-	char buf[cmdMAX_INPUT_SIZE];
-	char bufptr;
-	char prev_cmd[cmdMAX_INPUT_SIZE];
-	unsigned char optdata[cmdMAX_INPUT_SIZE];
-	uint8_t optlen;
-	state_telnet_server_t telnetState;
-	user_level_t telnet_code_auth;
-	char login[MAX_WEB_LOGIN_LEN];
-	uint8_t login_err;
-	uint8_t num_connect;
-	bool active_conn;
-	bool flagWhiteListTelnet;
-}telnetd_state_t;
-
 
 void telnet_server_init(void);