Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/vty.h b/vty.h
index 8f7a8411..0973e607 100644
--- a/vty.h
+++ b/vty.h
@@ -1,38 +1,41 @@
#ifndef __VTY_H__
#define __VTY_H__
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#define KNET_VTY_DEFAULT_PORT 50000
#define KNET_VTY_DEFAULT_MAX_CONN 4
#define KNET_VTY_TOTAL_MAX_CONN 16
#define KNET_VTY_CLI_TIMEOUT 60
+#define KNET_VTY_MAX_LINE 512
+
struct knet_vty {
pthread_t vty_thread; /* thread struct for this vty */
struct sockaddr_storage src_sa; /* source IP */
socklen_t src_sa_len; /* sa len */
char username[64]; /* username */
- char line[512]; /* input line */
+ char line[KNET_VTY_MAX_LINE]; /* input line */
int line_idx; /* index on the input line */
+ int cursor_pos; /* position of the cursor in the line */
int user_can_enable;/* user is in group kronosnetadm */
int vty_sock; /* tcp socket for this vty */
int conn_num; /* vty number */
int active; /* vty is active */
int got_epipe; /* vty_sock has been closed */
int idle; /* idle time */
int disable_idle; /* disable automatic logout */
};
int knet_vty_main_loop(const char *configfile, const char *ip_addr,
const char *port);
int knet_vty_init_listener(const char *address, const char *port);
void knet_vty_close_listener(int listener_fd);
int knet_vty_set_max_connections(const int max_connections);
#endif
diff --git a/vty_cli.c b/vty_cli.c
index 2f6e8e11..705ef185 100644
--- a/vty_cli.c
+++ b/vty_cli.c
@@ -1,50 +1,155 @@
#include "config.h"
#include <errno.h>
#include <sys/select.h>
+#include <unistd.h>
#include "utils.h"
#include "vty.h"
#include "vty_cli.h"
#include "vty_utils.h"
+/* if this code looks like quagga lib/vty.c it is because we stole it in part */
+
+#define CONTROL(X) ((X) - '@')
+#define VTY_NORMAL 0
+#define VTY_PRE_ESCAPE 1
+#define VTY_ESCAPE 2
+
+static const char telnet_backward_char = 0x08;
+static const char telnet_space_char = ' ';
+
+/*
+ * return = ^M <- 2 chars, go back 2 chars, write 2 spaces, go back 2 chars, go down
+ * this feels so old school poke!
+ */
+static const char telnet_newline[] = { 0x08, 0x08, ' ', ' ', 0x08, 0x08, '\n', 0x0 };
+
+static void knet_vty_reset_buf(struct knet_vty *vty)
+{
+ memset(vty->line, 0, sizeof(vty->line));
+ vty->line_idx = 0;
+ vty->cursor_pos = 0;
+}
+
+static void knet_vty_add_to_buf(struct knet_vty *vty, unsigned char *buf, int pos)
+{
+ vty->line[vty->line_idx] = buf[pos];
+ vty->line_idx++;
+ vty->cursor_pos++;
+}
+
static int knet_vty_process_buf(struct knet_vty *vty, unsigned char *buf, int buflen)
{
+ int i;
+
+ if (vty->line_idx >= KNET_VTY_MAX_LINE)
+ return -1;
+
+ for (i = 0; i <= buflen; i++) {
+ switch (buf[i]) {
+ case CONTROL('A'):
+ log_info("beginning of line");
+ break;
+ case CONTROL('B'):
+ log_info("backward char");
+ break;
+ case CONTROL('C'):
+ log_info("stop input");
+ break;
+ case CONTROL('D'):
+ log_info("delete char / go one level down");
+ break;
+ case CONTROL('E'):
+ log_info("end of line");
+ break;
+ case CONTROL('F'):
+ log_info("forward char");
+ break;
+ case CONTROL('H'):
+ case 0x7f:
+ log_info("delete backward char");
+ break;
+ case CONTROL('K'):
+ log_info("kill line");
+ break;
+ case CONTROL('N'):
+ log_info("next line");
+ break;
+ case CONTROL('P'):
+ log_info("previous line");
+ break;
+ case CONTROL('T'):
+ log_info("transport chars");
+ break;
+ case CONTROL('U'):
+ log_info("kill line from beginning");
+ break;
+ case CONTROL('W'):
+ log_info("kill backward word");
+ break;
+ case CONTROL('Z'):
+ log_info("end config");
+ break;
+ case '\n':
+ case '\r':
+ knet_vty_write(vty, "%s", telnet_newline);
+ knet_vty_reset_buf(vty);
+ break;
+ case '\t':
+ log_info("command completion");
+ break;
+ case '?':
+ log_info("help");
+ break;
+ case '\033':
+ log_info("escape: %d", buflen);
+ break;
+ default:
+ if (buf[i] > 31 && buf[i] < 127)
+ knet_vty_add_to_buf(vty, buf, i);
+ break;
+ }
+ }
+
return 0;
}
void knet_vty_cli_bind(struct knet_vty *vty)
{
int se_result = 0;
fd_set rfds;
struct timeval tv;
unsigned char buf[VTY_MAX_BUFFER_SIZE];
int readlen;
while (se_result >= 0 && !vty->got_epipe) {
FD_ZERO (&rfds);
FD_SET (vty->vty_sock, &rfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
se_result = select((vty->vty_sock + 1), &rfds, 0, 0, &tv);
if ((se_result == -1) || (vty->got_epipe))
goto out_clean;
if ((se_result == 0) || (!FD_ISSET(vty->vty_sock, &rfds)))
continue;
memset(buf, 0 , sizeof(buf));
readlen = knet_vty_read(vty, buf, sizeof(buf));
if (readlen <= 0)
goto out_clean;
- knet_vty_process_buf(vty, buf, readlen);
+ if (knet_vty_process_buf(vty, buf, readlen) < 0) {
+ knet_vty_write(vty, "\nError processing command: command too long\n");
+ knet_vty_reset_buf(vty);
+ }
}
out_clean:
return;
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jun 25, 2:15 AM (11 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1951849
Default Alt Text
(4 KB)

Event Timeline