summaryrefslogtreecommitdiff
path: root/lib/vty.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-01-17 21:01:56 -0500
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-01-17 21:01:56 -0500
commitb58ed1f8a89ea32c2380bf79057e5333109d72d4 (patch)
treea9ead45b8895edce92ab69621a52816b45725e36 /lib/vty.c
parent01cb1466423363a2f8b42246464feb3858df1c9f (diff)
parent5551c072e187c76c3d6a885cd043d6db811bab23 (diff)
Merge remote-tracking branch 'origin/master' into pim_lib_work2
Diffstat (limited to 'lib/vty.c')
-rw-r--r--lib/vty.c186
1 files changed, 51 insertions, 135 deletions
diff --git a/lib/vty.c b/lib/vty.c
index d5ecb1db5b..e47ad1e59a 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -508,18 +508,6 @@ vty_write (struct vty *vty, const char *buf, size_t nbytes)
buffer_put (vty->obuf, buf, nbytes);
}
-/* Ensure length of input buffer. Is buffer is short, double it. */
-static void
-vty_ensure (struct vty *vty, int length)
-{
- if (vty->max <= length)
- {
- vty->max *= 2;
- vty->buf = XREALLOC (MTYPE_VTY, vty->buf, vty->max);
- vty->error_buf = XREALLOC (MTYPE_VTY, vty->error_buf, vty->max);
- }
-}
-
/* Basic function to insert character into vty. */
static void
vty_self_insert (struct vty *vty, char c)
@@ -527,7 +515,9 @@ vty_self_insert (struct vty *vty, char c)
int i;
int length;
- vty_ensure (vty, vty->length + 1);
+ if (vty->length + 1 > VTY_BUFSIZ)
+ return;
+
length = vty->length - vty->cp;
memmove (&vty->buf[vty->cp + 1], &vty->buf[vty->cp], length);
vty->buf[vty->cp] = c;
@@ -544,26 +534,29 @@ vty_self_insert (struct vty *vty, char c)
static void
vty_self_insert_overwrite (struct vty *vty, char c)
{
- vty_ensure (vty, vty->length + 1);
- vty->buf[vty->cp++] = c;
-
- if (vty->cp > vty->length)
- vty->length++;
-
- if ((vty->node == AUTH_NODE) || (vty->node == AUTH_ENABLE_NODE))
- return;
+ if (vty->cp == vty->length)
+ {
+ vty_self_insert (vty, c);
+ return;
+ }
+ vty->buf[vty->cp++] = c;
vty_write (vty, &c, 1);
}
-/* Insert a word into vty interface with overwrite mode. */
+/**
+ * Insert a string into vty->buf at the current cursor position.
+ *
+ * If the resultant string would be larger than VTY_BUFSIZ it is
+ * truncated to fit.
+ */
static void
vty_insert_word_overwrite (struct vty *vty, char *str)
{
- int len = strlen (str);
- vty_write (vty, str, len);
- strcpy (&vty->buf[vty->cp], str);
- vty->cp += len;
+ size_t nwrite = MIN ((int) strlen (str), VTY_BUFSIZ - vty->cp);
+ vty_write (vty, str, nwrite);
+ strncpy (&vty->buf[vty->cp], str, nwrite);
+ vty->cp += nwrite;
vty->length = vty->cp;
}
@@ -1867,7 +1860,6 @@ vty_accept (struct thread *thread)
}
}
-#ifdef HAVE_IPV6
/* VTY's ipv6 accesslist apply. */
if (p.family == AF_INET6 && vty_ipv6_accesslist_name)
{
@@ -1884,7 +1876,6 @@ vty_accept (struct thread *thread)
return 0;
}
}
-#endif /* HAVE_IPV6 */
on = 1;
ret = setsockopt (vty_sock, IPPROTO_TCP, TCP_NODELAY,
@@ -1901,7 +1892,6 @@ vty_accept (struct thread *thread)
return 0;
}
-#ifdef HAVE_IPV6
static void
vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
{
@@ -1932,9 +1922,7 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
do
{
if (ainfo->ai_family != AF_INET
-#ifdef HAVE_IPV6
&& ainfo->ai_family != AF_INET6
-#endif /* HAVE_IPV6 */
)
continue;
@@ -1967,76 +1955,6 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
freeaddrinfo (ainfo_save);
}
-#else /* HAVE_IPV6 */
-
-/* Make vty server socket. */
-static void
-vty_serv_sock_family (const char* addr, unsigned short port, int family)
-{
- int ret;
- union sockunion su;
- int accept_sock;
- void* naddr=NULL;
-
- memset (&su, 0, sizeof (union sockunion));
- su.sa.sa_family = family;
- if(addr)
- switch(family)
- {
- case AF_INET:
- naddr=&su.sin.sin_addr;
- break;
-#ifdef HAVE_IPV6
- case AF_INET6:
- naddr=&su.sin6.sin6_addr;
- break;
-#endif
- }
-
- if(naddr)
- switch(inet_pton(family,addr,naddr))
- {
- case -1:
- zlog_err("bad address %s",addr);
- naddr=NULL;
- break;
- case 0:
- zlog_err("error translating address %s: %s",addr,safe_strerror(errno));
- naddr=NULL;
- }
-
- /* Make new socket. */
- accept_sock = sockunion_stream_socket (&su);
- if (accept_sock < 0)
- return;
-
- /* This is server, so reuse address. */
- sockopt_reuseaddr (accept_sock);
- sockopt_reuseport (accept_sock);
- set_cloexec (accept_sock);
-
- /* Bind socket to universal address and given port. */
- ret = sockunion_bind (accept_sock, &su, port, naddr);
- if (ret < 0)
- {
- zlog_warn("can't bind socket");
- close (accept_sock); /* Avoid sd leak. */
- return;
- }
-
- /* Listen socket under queue 3. */
- ret = listen (accept_sock, 3);
- if (ret < 0)
- {
- zlog (NULL, LOG_WARNING, "can't listen socket");
- close (accept_sock); /* Avoid sd leak. */
- return;
- }
-
- /* Add vty server event. */
- vty_event (VTY_SERV, accept_sock, NULL);
-}
-#endif /* HAVE_IPV6 */
#ifdef VTYSH
/* For sockaddr_un. */
@@ -2223,36 +2141,45 @@ vtysh_read (struct thread *thread)
printf ("line: %.*s\n", nbytes, buf);
#endif /* VTYSH_DEBUG */
- for (p = buf; p < buf+nbytes; p++)
+ if (vty->length + nbytes > VTY_BUFSIZ)
+ {
+ /* Clear command line buffer. */
+ vty->cp = vty->length = 0;
+ vty_clear_buf (vty);
+ vty_out (vty, "%% Command is too long.%s", VTY_NEWLINE);
+ }
+ else
{
- vty_ensure(vty, vty->length+1);
- vty->buf[vty->length++] = *p;
- if (*p == '\0')
+ for (p = buf; p < buf+nbytes; p++)
{
- /* Pass this line to parser. */
- ret = vty_execute (vty);
- /* Note that vty_execute clears the command buffer and resets
- vty->length to 0. */
+ vty->buf[vty->length++] = *p;
+ if (*p == '\0')
+ {
+ /* Pass this line to parser. */
+ ret = vty_execute (vty);
+ /* Note that vty_execute clears the command buffer and resets
+ vty->length to 0. */
- /* Return result. */
+ /* Return result. */
#ifdef VTYSH_DEBUG
- printf ("result: %d\n", ret);
- printf ("vtysh node: %d\n", vty->node);
+ printf ("result: %d\n", ret);
+ printf ("vtysh node: %d\n", vty->node);
#endif /* VTYSH_DEBUG */
- /* hack for asynchronous "write integrated"
- * - other commands in "buf" will be ditched
- * - input during pending config-write is "unsupported" */
- if (ret == CMD_SUSPEND)
- break;
+ /* hack for asynchronous "write integrated"
+ * - other commands in "buf" will be ditched
+ * - input during pending config-write is "unsupported" */
+ if (ret == CMD_SUSPEND)
+ break;
- /* warning: watchquagga hardcodes this result write */
- header[3] = ret;
- buffer_put(vty->obuf, header, 4);
+ /* warning: watchquagga hardcodes this result write */
+ header[3] = ret;
+ buffer_put(vty->obuf, header, 4);
- if (!vty->t_write && (vtysh_flush(vty) < 0))
- /* Try to flush results; exit if a write error occurs. */
- return 0;
+ if (!vty->t_write && (vtysh_flush(vty) < 0))
+ /* Try to flush results; exit if a write error occurs. */
+ return 0;
+ }
}
}
@@ -2279,14 +2206,7 @@ vty_serv_sock (const char *addr, unsigned short port, const char *path)
{
/* If port is set to 0, do not listen on TCP/IP at all! */
if (port)
- {
-
-#ifdef HAVE_IPV6
- vty_serv_sock_addrinfo (addr, port);
-#else /* ! HAVE_IPV6 */
- vty_serv_sock_family (addr,port, AF_INET);
-#endif /* HAVE_IPV6 */
- }
+ vty_serv_sock_addrinfo (addr, port);
#ifdef VTYSH
vty_serv_un (path);
@@ -2858,7 +2778,6 @@ DEFUN (no_vty_access_class,
return CMD_SUCCESS;
}
-#ifdef HAVE_IPV6
/* Set vty access class. */
DEFUN (vty_ipv6_access_class,
vty_ipv6_access_class_cmd,
@@ -2902,7 +2821,6 @@ DEFUN (no_vty_ipv6_access_class,
return CMD_SUCCESS;
}
-#endif /* HAVE_IPV6 */
/* vty login. */
DEFUN (vty_login,
@@ -3184,10 +3102,8 @@ vty_init (struct thread_master *master_thread)
install_element (VTY_NODE, &no_vty_access_class_cmd);
install_element (VTY_NODE, &vty_login_cmd);
install_element (VTY_NODE, &no_vty_login_cmd);
-#ifdef HAVE_IPV6
install_element (VTY_NODE, &vty_ipv6_access_class_cmd);
install_element (VTY_NODE, &no_vty_ipv6_access_class_cmd);
-#endif /* HAVE_IPV6 */
}
void