GophHub - go4retro/tcpser/src/nvt.c


Raw File

    1	#include <string.h>
    2	
    3	#include "debug.h"
    4	#include "ip.h"
    5	#include "modem_core.h"
    6	
    7	#include "nvt.h"
    8	
    9	void nvt_init_config(nvt_vars *vars) {
   10	  int i; 
   11	
   12	  vars->binary_xmit = FALSE;
   13	  vars->binary_recv = FALSE;
   14	  for (i = 0; i < 256; i++)
   15	    vars->term[i] = 0;
   16	}
   17	
   18	unsigned char get_nvt_cmd_response(unsigned char action, unsigned char type) {
   19	  unsigned char rc = 0;
   20	
   21	  if(type == TRUE) {
   22	    switch (action) {
   23	      case NVT_DO:
   24	        rc = NVT_WILL;
   25	        break;
   26	      case NVT_DONT:
   27	        rc = NVT_WONT;
   28	        break;
   29	      case NVT_WILL:
   30	        rc = NVT_DO;
   31	        break;
   32	      case NVT_WONT:
   33	        rc = NVT_DONT;
   34	        break;
   35	    }
   36	  } else {
   37	    switch (action) {
   38	      case NVT_DO:
   39	      case NVT_DONT:
   40	        rc = NVT_WONT;
   41	        break;
   42	      case NVT_WILL:
   43	      case NVT_WONT:
   44	        rc = NVT_DONT;
   45	        break;
   46	    }
   47	  }
   48	  return rc;
   49	}
   50	
   51	int parse_nvt_subcommand(dce_config *cfg, int fd, nvt_vars *vars, unsigned char *data, int len) {
   52	  // overflow issue, again...
   53	  nvt_option opt = data[2];
   54	  unsigned char resp[100];
   55	  unsigned char *response = resp + 3;
   56	  int resp_len = 0;
   57	  int response_len = 0;
   58	  char tty_type[] = "VT100";
   59	  int rc;
   60	  char buf[50];
   61	  int slen = 0;
   62	
   63	  for (rc = 2; rc < len - 1; rc++) {
   64	    if (NVT_IAC == data[rc])
   65	      if (NVT_SE == data[rc + 1]) {
   66	        rc += 2;
   67	        break;
   68	      }
   69	  }
   70	
   71	  if (rc > 5 && (NVT_SB_SEND == data[3])) {
   72	    switch(opt) {
   73	      case NVT_OPT_TERMINAL_TYPE:
   74	      case NVT_OPT_X_DISPLAY_LOCATION:  // should not have to have these
   75	      case NVT_OPT_ENVIRON:             // but telnet seems to expect.
   76	      case NVT_OPT_NEW_ENVIRON:         // them.
   77	      case NVT_OPT_TERMINAL_SPEED:
   78	        response[response_len++] = NVT_SB_IS;
   79	        switch(opt) {
   80	          case NVT_OPT_TERMINAL_TYPE:
   81	            slen = strlen(tty_type);
   82	            strncpy((char *)response + response_len, tty_type, slen);
   83	            response_len += slen;
   84	            break;
   85	          case NVT_OPT_TERMINAL_SPEED:
   86	            sprintf(buf, "%i,%i", cfg->port_speed, cfg->port_speed);
   87	            slen = strlen(buf);
   88	            strncpy((char *)response + response_len, buf, slen);
   89	            response_len += slen;
   90	            break;
   91	          default:
   92	            break;
   93	        }
   94	        break;
   95	      default:
   96	        break;
   97	    }
   98	  }
   99	
  100	  if (response_len) {
  101	    resp[resp_len++] = NVT_IAC;
  102	    resp[resp_len++] = NVT_SB;
  103	    resp[resp_len++] = opt;
  104	    resp_len += response_len;
  105	    resp[resp_len++] = NVT_IAC;
  106	    resp[resp_len++] = NVT_SE;
  107	    ip_write(fd, resp, resp_len);
  108	  }
  109	  return rc;
  110	}
  111	
  112	void get_action(char *txt, nvt_command action) {
  113	  switch (action) {
  114	  case NVT_WILL:
  115	    strcpy(txt, "WILL");
  116	    break;
  117	  case NVT_WONT:
  118	    strcpy(txt, "WONT");
  119	    break;
  120	  case NVT_DO:
  121	    strcpy(txt, "DO");
  122	    break;
  123	  case NVT_DONT:
  124	    strcpy(txt, "DONT");
  125	    break;
  126	  default:
  127	    strcpy(txt, "UNKNOWN");
  128	    break;
  129	  }
  130	}
  131	
  132	int send_nvt_command(int fd, nvt_vars *vars, nvt_command action, nvt_option opt) {
  133	  unsigned char cmd[3];
  134	  char txt[20];
  135	
  136	  get_action(txt, action);
  137	  LOG(LOG_DEBUG, "Sending NVT command: %s %d", txt, opt);
  138	  cmd[0] = NVT_IAC;
  139	  cmd[1] = action;
  140	  cmd[2] = opt;
  141	
  142	  ip_write(fd, cmd, 3);
  143	  vars->term[opt] = action;
  144	
  145	  return 0;
  146	}
  147	
  148	int parse_nvt_command(dce_config *cfg, int fd, nvt_vars *vars, nvt_command action, nvt_option opt) {
  149	  int accept = FALSE;
  150	  char txt[20];
  151	  int resp;
  152	
  153	  get_action(txt, action);
  154	  LOG(LOG_DEBUG, "Received NVT command: %s %d", txt, opt);
  155	  switch (opt) {
  156	    case NVT_OPT_TRANSMIT_BINARY :
  157	      switch (action) {
  158	        case NVT_DO:
  159	          if(!dce_get_parity(cfg)) {
  160	            LOG(LOG_INFO, "Enabling telnet binary xmit");
  161	            vars->binary_xmit = TRUE;
  162	            accept = TRUE;
  163	          }
  164	          break;
  165	        case NVT_DONT:
  166	          LOG(LOG_INFO, "Disabling telnet binary xmit");
  167	          vars->binary_xmit = FALSE;
  168	          accept = TRUE;
  169	          break;
  170	        case NVT_WILL:
  171	          if(!dce_get_parity(cfg)) {
  172	            LOG(LOG_INFO, "Enabling telnet binary recv");
  173	            vars->binary_recv = TRUE;
  174	            accept = TRUE;
  175	          }
  176	          break;
  177	        case NVT_WONT:
  178	          LOG(LOG_INFO, "Disabling telnet binary recv");
  179	          vars->binary_recv = FALSE;
  180	          accept = TRUE;
  181	          break;
  182	        default:
  183	          break;
  184	      }
  185	      resp = get_nvt_cmd_response(action, accept);
  186	      break;
  187	    case NVT_OPT_NAWS:
  188	    case NVT_OPT_TERMINAL_TYPE:
  189	    case NVT_OPT_SUPPRESS_GO_AHEAD:
  190	    case NVT_OPT_ECHO:
  191	    case NVT_OPT_X_DISPLAY_LOCATION:  // should not have to have these
  192	    case NVT_OPT_ENVIRON:             // but telnet seems to expect.
  193	    case NVT_OPT_NEW_ENVIRON:         // them.
  194	    case NVT_OPT_TERMINAL_SPEED:
  195	      resp = get_nvt_cmd_response(action, TRUE);
  196	      break;
  197	    default:
  198	      resp = get_nvt_cmd_response(action, FALSE);
  199	      break;
  200	  }
  201	  send_nvt_command(fd, vars, resp, opt);
  202	  return 0;
  203	}
  204	

Generated by GNU Enscript 1.6.6, and GophHub 1.3.