Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4511720
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rK kronosnet
Attached
Detach File
Event Timeline
Log In to Comment