Logo Search packages:      
Sourcecode: yersinia version File versions

commands.c

/* commands.c
 * Implementation of Cisco CLI commands
 *
 * Yersinia
 * By David Barroso <tomac@wasahero.org> and Alfredo Andres <slay@wasahero.org>
 * Copyright 2005 Alfredo Andres and David Barroso
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#ifndef lint
static const char rcsid[] = 
       "$Id: commands.c,v 1.4 2005/07/28 19:29:24 t0mac Exp $";
#endif

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
 
#define _REENTRANT

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>       

#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#else
#ifdef HAVE_NETINET_IN_SYSTEM_H
#include <netinet/in_system.h>
#endif
#endif

#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <time.h>

#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif

#ifdef HAVE_BSTRING_H
#include <bstring.h>
#endif

#ifdef STDC_HEADERS
#include <stdlib.h>
#endif

#include <stdarg.h>

#ifdef SOLARIS
#include <pthread.h>
#include <thread.h>
#else
#include <pthread.h>
#endif


#include "commands.h"

/* 
 * Select what command do.
 * Return -1 on error. Return 0 if Ok.
 */
int8_t
command_select_comm(struct term_node *node, struct words_array *warray, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (warray->nwords == (warray->indx+1) )
      params = 0;
   else
      params = 1;

   i = j = gotit = 0;

   while(comm_common[i].s != NULL)
   {
      if (comm_common[i].states[node->state])
      {   
         if (!strncmp(comm_common[i].s, warray->word[warray->indx], strlen(warray->word[warray->indx])))
         {
            if (help && !params)
            {
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_common[i].s,comm_common[i].help);
               fail=term_vty_write(node,msg,strlen(msg));
               if (fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx]) == strlen(comm_common[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,0);
      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit == 1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
            fail = (comm_common[j].command(node,warray,j,help,help_as_param));
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if (!help || (help && params))
         {
            vty->repeat_command= 0;
            if (help || help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;
}




/*
 * Comando de prueba para probar el modo More... 
 */
int8_t
command_prueba(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   int8_t fail;
   char msg[128];
   u_int8_t i;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help || help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_common[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }
   
   fail = term_vty_write(node,"\r\n",2);

   if (fail == -1)
      return -1;
   
   for(i=0; i< 250; i++)
   {
      snprintf(msg,sizeof(msg),"%d - Esta es la linea %d\r\n",i,i);
      fail = term_vty_write(node,msg, strlen(msg));
      if (fail)
         break;
   }
   
   return fail;
}


/*
 * Clear client screen...
 * Return 0 if Ok. Return -1 if error.
 */
int8_t
command_cls(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   int8_t fail;
   struct term_vty *vty = node->specific;
   char msg[128];
      
   if (warray && (warray->word[warray->indx+1]))
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help || help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_common[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }

   fail = term_vty_write(node,"\r\n",2);
   
   if (fail==-1)
      return -1;
   
   fail = term_vty_write(node,CLEAR_SCREEN,strlen(CLEAR_SCREEN));

   if (fail==-1)
      return -1;
   
   vty->clearmode=1;

   return 0;
}


/* 
 * Show global help
 */
int8_t
command_help(struct term_node *node)
{
  int8_t i, fail;
  char msg[128];
  
  i = 0;
  
  while(comm_common[i].s != NULL)
  {
     if (comm_common[i].states[node->state])
     {
        snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_common[i].s,comm_common[i].help);
        fail=term_vty_write(node,msg,strlen(msg));
        if (fail==-1)
           return -1;
     }  
     i++;
  }

  return 0;
}


/*
 * Come back to previous level
 * Return 0 if Ok. Return -1 if error (or going to exit level).
 */
int8_t
command_disable(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   return (command_exit(node, warray, j, help, help_as_param));
}


/*
 * Come back to previous level
 * Return 0 if Ok. Return -1 if error (or going to exit level).
 */
int8_t
command_exit(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   int8_t fail;
   char msg[128];
   struct term_vty *vty = node->specific;

   if (warray && (warray->word[warray->indx+1]))
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help || help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_common[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }

   return (term_vty_exit(node));   
}




int8_t
command_who(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   return (command_show_users(node,warray,j,help,help_as_param));
}




int8_t
command_enable(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   int8_t fail;
   char msg[128];
   struct term_vty *vty = node->specific;
      
   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help || help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_common[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }
      
   vty->authing=1;
   
   return 0;
}


int8_t
command_cancel(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;
      
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"cancel ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_cancel[i].s != NULL)
       {
          if (comm_cancel[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_cancel[i].s,comm_cancel[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_cancel[i].s != NULL)
   {
      if (comm_cancel[i].states[node->state])
      {   
         if (!strncmp(comm_cancel[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            {
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_cancel[i].s,comm_cancel[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_cancel[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);
      
      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            if (comm_cancel[j].proto == 255) /* Cancel ALL */
               fail = command_cancel_attacks(node,warray,j,help,help_as_param);
            else
               fail = command_cancel_proto(node,warray,j,help,help_as_param,comm_cancel[j].proto);
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || (help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help || help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;
}



int8_t
command_cancel_proto(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param, 
                    u_int8_t proto)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (help && !params)
      return 0;
    
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"cancel %s ?\" for a list of subcommands",warray->word[warray->indx]);
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_cancel_proto[i].s != NULL)
       {
          if (comm_cancel_proto[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_cancel_proto[i].s,comm_cancel_proto[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_cancel_proto[i].s != NULL)
   {
      if (comm_cancel_proto[i].states[node->state])
      {   
         if (!strncmp(comm_cancel_proto[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            { 
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_cancel_proto[i].s,comm_cancel_proto[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_cancel_proto[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = command_cancel_proto2(node,warray,j,help,help_as_param,proto);
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || ( help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;   
}


int8_t
command_cancel_proto2(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param,
                       u_int8_t proto)
{
   char msg[128];
   int8_t fail, params, aux;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (warray->nwords > (warray->indx+2))
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments: \"%s\".\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments: \"%s\".", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help && !params)
      return 0;

   if ( (help_as_param && !params) ||
        (help && params) )
   {
      int8_t i;
      char *string = comm_cancel_proto[x].params;
      for(i=0; i<comm_cancel_proto[x].nparams; i++)
      {   
          snprintf(msg,sizeof(msg),"  %-30s\r\n",string);
          string+=strlen(string)+1;
          fail = term_vty_write(node,msg,strlen(msg));
          if (fail == -1)
             return -1;
      }
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (!params)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Incomplete command.");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   if (help_as_param && (warray->nwords == (warray->indx+2)) )
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   /* Ok, now we have just 1 arg, begin parsing...*/
   aux = atoi(warray->word[warray->indx+1]);
   
   if ( (aux < 0) || (aux >= MAX_THREAD_ATTACK) )
      return (command_bad_input(node,warray->indx+1));

   /* Is running the attack?...*/
   if (!node->protocol[proto].attacks[aux].up)
   {
       snprintf(msg,sizeof(msg),"\r\n%% %s attack id \"%d\" not used",protocols[proto].name,aux);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }

   fail = attack_kill_th(node, node->protocol[proto].attacks[aux].attack_th.id);
   
   return 0;
}


int8_t
command_cancel_attacks(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   attack_kill_th(node, ALL_ATTACK_THREADS);
                       
   return 0;
}



/*
 * Command 'show'
 */
int8_t
command_show(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;
      
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"show ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_show[i].s != NULL)
       {
          if (comm_show[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_show[i].s,comm_show[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_show[i].s != NULL)
   {
      if (comm_show[i].states[node->state])
      {   
         if (!strncmp(comm_show[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            {
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_show[i].s,comm_show[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_show[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         { 
            warray->indx++;
            if (comm_show[j].proto != 255) /* Specific for protocol */
               fail = command_show_proto(node,warray,j,help,help_as_param,comm_show[j].proto);
            else
               fail = (comm_show[j].command(node,warray,j,help,help_as_param));
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || (help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help || help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;
}




/* 
 * Show users connected.
 * Use terms and term_type global pointer.
 * Return 0 if Ok. Return -1 on error.
 */
int8_t
command_show_users(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   char msg[128];
   int8_t i, fail;
   struct term_node *term_cursor;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_show[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }

   snprintf(msg,sizeof(msg),"\r\n   User         Terminal        From             Since\r\n");
   
   fail = term_vty_write(node,msg, strlen(msg));
   
   if (fail == -1)
      return -1;
      
   snprintf(msg,sizeof(msg),"   ----         --------        ----             -----\r\n");
   
   fail = term_vty_write(node,msg, strlen(msg));   
   
   if (fail == -1)
      return -1;
      
   term_cursor = terms->list;

   for(i=0; i<MAX_TERMS; i++)
   {  
      if (term_cursor->up)
      {
         if (term_cursor->thread.id == pthread_self())
         {
            snprintf(msg,sizeof(msg),"*  %-12s %7s%-2d %15s:%-5d  %4s\r\n",
                   term_cursor->username,  term_type[term_cursor->type].name,
                   term_cursor->number,    term_cursor->from_ip,
                   term_cursor->from_port, term_cursor->since); 
         }
         else
         {
            snprintf(msg,sizeof(msg),"   %-12s %7s%-2d %15s:%-5d  %4s\r\n",
                   term_cursor->username,  term_type[term_cursor->type].name,
                   term_cursor->number,    term_cursor->from_ip,
                   term_cursor->from_port, term_cursor->since); 
         }
         fail = term_vty_write(node,msg, strlen(msg));
         if (fail==-1)
            return -1;
      }
      term_cursor++;
   }

   return 0;
}


/* 
 * Show command line history.
 * Return 0 if Ok. Return -1 on error.
 */
int8_t
command_show_history(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   char msg[128];
   int8_t i, fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_show[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }

   for(i=0; i<MAX_HISTORY; i++)
   {
      if (vty->history[i] == NULL)
         break;
      snprintf(msg,sizeof(msg),"\r\n  %s",vty->history[i]);
      if (term_vty_write(node, msg, strlen(msg)) < 0)
         return -1;
   }   

   return 0;
}


/* 
 * Show all running attacks.
 * Return 0 if Ok. Return -1 on error.
 */
int8_t
command_show_attacks(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   char msg[128];
   int8_t fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_show[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }

   fail = command_proto_attacks(node,6666);
   
   return fail;
}



/* 
 * Show active interfaces
 * Return -1 on error. Return 0 if Ok.
 * Use global interfaces array (interfaces) and 
 * mutex associated (mutex_int).
 */
int8_t
command_show_interfaces(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   int8_t i, fail;
   char msg[128];
   struct term_vty *vty = node->specific;   

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_show[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }

   if (pthread_mutex_lock(&mutex_int) != 0)
   {
      thread_error("command_show_ints pthread_mutex_lock",errno);
      return -1;
   }

   for (i = 0; i < MAX_INTERFACES; i++) 
   {
      if (interfaces[i].ifname[0])
      {
         if (show_interface_data(node,i) < 0)
         {
            pthread_mutex_unlock(&mutex_int);
            return -1;
         } 
      }
   }
   
   if (pthread_mutex_unlock(&mutex_int) != 0)
   {
      thread_error("command_show_ints pthread_mutex_unlock",errno);
      return -1;
   }
   
   return 0;
}


int8_t
show_interface_data(struct term_node *node, u_int8_t iface)
{
   char msg[128], timebuf[30];
   
   snprintf(msg, sizeof(msg), "\r\n%s is up, line protocol is %s\r\n   Hardware is %s (%s),",
               interfaces[iface].ifname,
               (interfaces[iface].up)?"up":"down",
               (interfaces[iface].iflink_desc[0])?interfaces[iface].iflink_desc:"*unknown*",
               (interfaces[iface].iflink_name[0])?interfaces[iface].iflink_name:"??" );
  
   if (term_vty_write(node, msg, strlen(msg)) < 0)
      return -1;
   
   if (!memcmp(interfaces[iface].etheraddr,"\x0\x0\x0\x0\x0\x0",6))
      snprintf(msg, sizeof(msg), " no address suitable for this interface\r\n");
   else
      snprintf(msg, sizeof(msg), " address is %02x%02x.%02x%02x.%02x%02x (bia %02x%02x.%02x%02x.%02x%02x)\r\n",
             interfaces[iface].etheraddr[0], interfaces[iface].etheraddr[1],
             interfaces[iface].etheraddr[2], interfaces[iface].etheraddr[3],
             interfaces[iface].etheraddr[4], interfaces[iface].etheraddr[5],
             interfaces[iface].etheraddr[0], interfaces[iface].etheraddr[1],
             interfaces[iface].etheraddr[2], interfaces[iface].etheraddr[3],
             interfaces[iface].etheraddr[4], interfaces[iface].etheraddr[5]);
               
   if (term_vty_write(node, msg, strlen(msg)) < 0)
      return -1;
   
   if (interfaces[iface].ipaddr[0]) /* Print8_tIP data...*/
   {
      snprintf(msg, sizeof(msg), "   Internet address is %s/%s\r\n",
                 interfaces[iface].ipaddr, interfaces[iface].netmask);
      if (term_vty_write(node, msg, strlen(msg)) < 0)
         return -1;
      
      if (interfaces[iface].broadcast[0])
         snprintf(msg, sizeof(msg), "   Broadcast address is %s\r\n",
                 interfaces[iface].broadcast);
      else
         snprintf(msg, sizeof(msg), "   Broadcast address is not assigned\r\n");
      if (term_vty_write(node, msg, strlen(msg)) < 0)
          return -1;
    
      if (interfaces[iface].ptpaddr[0])
      {            
         snprintf(msg, sizeof(msg), "   Point8_tto Point8_taddress is %s\r\n",
                 interfaces[iface].ptpaddr);
         if (term_vty_write(node, msg, strlen(msg)) < 0)
             return -1;
      }
   }
   else
   {
      snprintf(msg, sizeof(msg), "   Internet address is not assigned\r\n");
      if (term_vty_write(node, msg, strlen(msg)) < 0)
          return -1;
   }
   
   snprintf(msg, sizeof(msg), "   Users using it %d\r\n",
             interfaces[iface].users);
                     
   if (term_vty_write(node, msg, strlen(msg)) < 0)
      return -1;
   
   snprintf(msg, sizeof(msg), "     %d input Spanning Tree packets\r\n",
             interfaces[iface].packets[PROTO_STP]);

   if (term_vty_write(node, msg, strlen(msg)) < 0)
      return -1;

/*   snprintf(msg, sizeof(msg),    "%d conf BPDU (%d%%), %d tcn BPDU (%d%%)\r\n",
             interfaces[iface].packets[PROTO_STP],
(interfaces[iface].packets[PROTO_STP])?
(interfaces[iface].packets[PROTO_STP]*100)
/interfaces[iface].packets[PROTO_STP]:0,
             interfaces[iface].packets[PROTO_STP],
(interfaces[iface].packets[PROTO_STP])?
(interfaces[iface].packets[PROTO_STP]*100)
/interfaces[iface].packets[PROTO_STP]:0 );

   if (term_vty_write(node, msg, strlen(msg)) < 0)
      return -1;      
*/
   if (interfaces[iface].packets[PROTO_STP])
   {
#ifdef HAVE_CTIME_R         
#ifdef SOLARIS
      ctime_r((time_t *)&protocols[PROTO_STP].stats[iface].header->ts,timebuf,sizeof(timebuf));
#else
      ctime_r((time_t *)&protocols[PROTO_STP].stats[iface].header->ts,timebuf);
#endif
      timebuf[strlen(timebuf)-1] = 0;
      snprintf(msg, sizeof(msg), "         Latest BPDU seen at %s\r\n",
                timebuf);
#else
      pthread_mutex_lock(&mutex_ctime);
      strncpy(timebuf,ctime((time_t *)&packet_stats.stp_stats[iface].header->ts),24);
      snprintf(msg, sizeof(msg), "         Latest BPDU seen at %s\r\n",
                 timebuf);
      pthread_mutex_unlock(&mutex_ctime);                      
#endif
   }
   else
       snprintf(msg, sizeof(msg), "        Spanning Tree packets not seen yet\r\n");
                     
   if (term_vty_write(node, msg, strlen(msg)) < 0)
      return -1;

   snprintf(msg, sizeof(msg), "     %d output Spanning Tree packets, ",
             interfaces[iface].packets[PROTO_STP] +
             interfaces[iface].packets[PROTO_STP] );

   if (term_vty_write(node, msg, strlen(msg)) < 0)
      return -1;      

   snprintf(msg, sizeof(msg), "%d conf BPDU (%d%%), %d tcn BPDU (%d%%)\r\n",
             interfaces[iface].packets[PROTO_STP],
(interfaces[iface].packets[PROTO_STP] + interfaces[iface].packets[PROTO_STP])?
(interfaces[iface].packets[PROTO_STP]*100)
/(interfaces[iface].packets[PROTO_STP] + interfaces[iface].packets[PROTO_STP]):0,

             interfaces[iface].packets[PROTO_STP],
(interfaces[iface].packets[PROTO_STP] + interfaces[iface].packets[PROTO_STP])?
(interfaces[iface].packets[PROTO_STP]*100)
/(interfaces[iface].packets[PROTO_STP] + interfaces[iface].packets[PROTO_STP]):0 );

   if (term_vty_write(node, msg, strlen(msg)) < 0)
      return -1;      


   snprintf(msg, sizeof(msg), "     %d input Cisco Discovery packets\r\n",
             interfaces[iface].packets[PROTO_CDP]);

   if (term_vty_write(node, msg, strlen(msg)) < 0)
      return -1;
   
   if (interfaces[iface].packets[PROTO_CDP])
   {
#ifdef HAVE_CTIME_R         
#ifdef SOLARIS
      ctime_r((time_t *)&protocols[PROTO_CDP].stats[iface].header->ts,timebuf,sizeof(timebuf));
#else
      ctime_r((time_t *)&protocols[PROTO_CDP].stats[iface].header->ts,timebuf);
#endif
      timebuf[strlen(timebuf)-1] = 0;
      snprintf(msg, sizeof(msg), "       Latest packet seen at %s with MAC XXXXXX",
                timebuf);
#else
      pthread_mutex_lock(&mutex_ctime);
      strncpy(timebuf,ctime((time_t *)&packet_stats.cdp_stats[iface].header->ts),24);
      snprintf(msg, sizeof(msg), "       Latest packet seen at %s with MAC XXXXXXX",
                 timebuf);
      pthread_mutex_unlock(&mutex_ctime);                      
#endif
   }
   else
       snprintf(msg, sizeof(msg), "      Cisco Discovery packets not seen");
                     
   if (term_vty_write(node, msg, strlen(msg)) < 0)
      return -1;
   
   return 0;

}

int8_t
command_show_version(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   int8_t fail;
   char msg[128];
   struct term_vty *vty = node->specific;   

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help)
   {
      return 0;
   }

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_show[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }

   snprintf(msg,sizeof(msg),"\r\nChaos Internetwork Operating System Software\r\n");
   if (term_vty_write(node,msg, strlen(msg))<0)
      return -1;

   snprintf(msg,sizeof(msg),""PACKAGE" (tm) Software ("INFO_PLATFORM"), Version "VERSION", RELEASE SOFTWARE\r\n");
   if (term_vty_write(node,msg, strlen(msg)) < 0)
      return -1;
   
   snprintf(msg,sizeof(msg),"Copyright (c) 2004-2004 by tomac & Slay, Inc.\r\n");
   if (term_vty_write(node,msg, strlen(msg)) < 0)
      return -1;

   snprintf(msg,sizeof(msg),"Compiled "INFO_DATE" by someone\r\n\r\n");
   if (term_vty_write(node,msg, strlen(msg)) < 0)
      return -1;

   if ( uptime < 60 )
      snprintf(msg,sizeof(msg),""PACKAGE" uptime is %02d seconds\r\n\r\n", uptime);
   else
   {
      if ( uptime < 3600 )
         snprintf(msg,sizeof(msg),""PACKAGE" uptime is %02d minutes, %02d seconds\r\n\r\n",
                      uptime / 60, uptime % 60);
      else
      {
         if ( uptime < (3600*24) )
         {
            snprintf(msg,sizeof(msg),""PACKAGE" uptime is %02d hours, %02d minutes, %02d seconds\r\n\r\n", 
                      uptime / 3600, (uptime % 3600) / 60, uptime % 60);
         }
         else
            snprintf(msg,sizeof(msg),""PACKAGE" uptime is %02d days, %02d hours, %02d minutes, %02d seconds\r\n\r\n",
                   uptime / (3600*24), (uptime % (3600*24)) / 3600, 
                   (uptime % 3600) / 60, uptime % 60);
      }
   }

   if (term_vty_write(node,msg, strlen(msg)) < 0)
      return -1;

   snprintf(msg,sizeof(msg),"Running Multithreading Image on "INFO_KERN" "INFO_KERN_VER" supporting:\r\n");
   if (term_vty_write(node,msg, strlen(msg)) < 0)
      return -1;

   snprintf(msg,sizeof(msg),"%02d console terminal(s)\r\n%02d tty terminal(s)\r\n%02d vty terminal(s)\r\n",
                             MAX_CON, MAX_TTY, MAX_VTY);
   fail = term_vty_write(node,msg, strlen(msg));
   
   return fail;
}


/*
 * Show statistics
 */
int8_t
command_show_stats(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param)
{
   return 0;
}


/*
 * Show protocol info
 */
int8_t
command_show_proto(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param,
                   u_int8_t proto)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (help && !params)
      return 0;
    
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"show %s ?\" for a list of subcommands",warray->word[warray->indx]);
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_show_proto[i].s != NULL)
       {
          if (comm_show_proto[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_show_proto[i].s,comm_show_proto[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_show_proto[i].s != NULL)
   {
      if (comm_show_proto[i].states[node->state])
      {   
         if (!strncmp(comm_show_proto[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            { 
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_show_proto[i].s,comm_show_proto[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_show_proto[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            switch(j)
            {
               case SHOW_ATTACKS:
                    fail = command_show_proto_attacks(node,warray,j,help,help_as_param,proto);
               break;
               case SHOW_PARAMS:
                    fail = command_show_proto_params(node,warray,j,help,help_as_param,proto);
               break;
               case SHOW_STATS:
                    fail = command_show_proto_stats(node,warray,j,help,help_as_param,proto);
               break;
            }
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || ( help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;
}


/*
 * Show proto attacks
 */
int8_t
command_show_proto_attacks(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param,
                            u_int8_t proto)
{
   char msg[128];
   int8_t fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_show_proto[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }

   fail = command_proto_attacks(node,proto);
   
   return fail;
}


/*
 * Show proto stats
 */
int8_t
command_show_proto_stats(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param,
                         u_int8_t proto)
{
   return 0;
}


/*
 * Show proto attack parameters
 */
int8_t
command_show_proto_params(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param,
                          u_int8_t proto)
{
   return 0;
}


/* 
 * Show active attacks.
 * If proto == 6666 show attacks from all protocols
 * Return 0 if Ok. Return -1 if error.
 */
int8_t
command_proto_attacks(struct term_node *node, u_int16_t proto)
{
   int8_t i,j;
   char msg[128];
   struct attack *theattack=NULL;
  
   snprintf(msg,sizeof(msg),"\r\n   No.    Protocol    Attack\r\n");
   if (term_vty_write(node,msg, strlen(msg)) < 0)
      return -1;
      
   snprintf(msg,sizeof(msg),"   ---    --------    ------");
   if (term_vty_write(node,msg, strlen(msg)) < 0)
      return -1;

   for (j=0; j < MAX_PROTOCOLS; j++)
   {
       if (proto != 6666)
          j=proto;

       theattack = protocols[j].attacks;
       for (i=0; i < MAX_THREAD_ATTACK; i++)
       {
           if (node->protocol[j].attacks[i].up)
           {
               snprintf(msg,sizeof(msg), "\r\n    %-1d      %-8s   %s", i,
                           node->protocol[j].name,
                           theattack[node->protocol[j].attacks[i].attack].s);
               if (term_vty_write(node,msg,strlen(msg)) < 0)
                  return -1;
           }
       }
       if (proto != 6666)
          break;
   }
                                                                    
   return 0;
}



/*
 * Command 'clear'
 */
int8_t
command_clear(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;
      
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"clear ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_clear[i].s != NULL)
       {
          if (comm_clear[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_clear[i].s,comm_clear[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_clear[i].s != NULL)
   {
      if (comm_clear[i].states[node->state])
      {   
         if (!strncmp(comm_clear[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            {
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_clear[i].s,comm_clear[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_clear[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         { 
            warray->indx++;
            fail = command_clear_proto(node,warray,j,help,help_as_param,comm_clear[j].proto);
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || (help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help || help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;
}


/* 
 * Clear protocol stats
 */
int8_t
command_clear_proto(struct term_node *node, struct words_array *warray, int16_t j, int8_t help, int8_t help_as_param,
                        u_int8_t proto)
{
   char msg[128];
   int8_t fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
       {
          snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
          fail = term_vty_write(node,msg, strlen(msg));
       }
       else
          fail = command_bad_input(node,warray->indx+1);
       return fail;
   }
        
   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"  %-10s\r\n",comm_clear[j].params);
      fail = term_vty_write(node,msg,strlen(msg));
      vty->repeat_command= 1;
      return fail;
   }

   if (proto == 255)
      fail = interfaces_clear_stats(PROTO_ALL);
   else
      fail = interfaces_clear_stats(proto);
   
   if (fail == -1)
      return -1;

   return 0;
}



/*
 * Command set
 */
int8_t
command_set(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;
      
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"set ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_set[i].s != NULL)
       {
          if (comm_set[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set[i].s,comm_set[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_set[i].s != NULL)
   {
      if (comm_set[i].states[node->state])
      {   
         if (!strncmp(comm_set[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            {
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set[i].s,comm_set[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_set[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);
      
      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = (comm_set[j].command(node,warray,j,help,help_as_param));
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || (help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help || help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;
}


/*
 * Command set STP 
 */
int8_t
command_set_stp(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (help && !params)
      return 0;
    
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"set stp ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_set_stp[i].s != NULL)
       {
          if (comm_set_stp[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_stp[i].s,comm_set_stp[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_set_stp[i].s != NULL)
   {
      if (comm_set_stp[i].states[node->state])
      {   
         if (!strncmp(comm_set_stp[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            { 
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_stp[i].s,comm_set_stp[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_set_stp[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = (comm_set_stp[j].command(node,warray,j,help,help_as_param));
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || ( help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;   
}



/*
 * Command set STP general
 * All general commands must have just 1 argument...
 */
int8_t
command_set_stp_general(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128], *args;
   char prova;
   int8_t fail, i, params;
   u_int8_t aux;
   char *punt;
   struct stp_data *stp_data;
   struct term_vty *vty = node->specific;

   args = warray->word[warray->indx+1];

   if (!args)
      params=0;
   else
      params=1;

   if (warray->nwords > (warray->indx+2))
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\".\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\".", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help && !params)
      return 0;

   if ( (help_as_param && !params) ||
        (help && params) )
   {
      char *string = comm_set_stp[x].params;
      for(i=0; i<comm_set_stp[x].nparams; i++)
      {   
          snprintf(msg,sizeof(msg),"  %-30s\r\n",string);
          string+=strlen(string)+1;
          fail = term_vty_write(node,msg,strlen(msg));
          if (fail == -1)
             return -1;
      }
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (help_as_param && (warray->nwords == (warray->indx+2)) )
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (!params)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Incomplete command.");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }
   
   /* Ok, now we have just 1 arg, begin parsing...*/

   stp_data = node->protocol[PROTO_STP].tmp_data;
   
   if (!strcmp("interface", comm_set_stp[x].s))
   {
      int8_t tmp;
      if ((tmp = interfaces_get(args)) == -1)
      {
         fail = command_bad_input(node,warray->indx+1);
         return fail;
      }
       /* Don't repeat interface...*/
      if (!node->used_ints[tmp])
      {
          if ((tmp = interfaces_add(args)) == -1)
          {
             fail = command_bad_input(node,warray->indx+1);
             return fail;
          }
          node->used_ints[tmp] = 1;
      }
      return 0;
   }

   if (!strcmp("version", comm_set_stp[x].s))
   {
      parser_str_tolower(args);
      if (!strcmp("rstp",args))
      {
          stp_data->version   = RSTP_VERSION;
          memcpy((void *)stp_data->rstp_data, (void *)"\x00", 1);
          stp_data->rstp_len  = 1;
          return 0;
      }
      if (!strcmp("stp",args))
      {
          stp_data->version = STP_VERSION;
          return 0;
      }
      return (command_bad_input(node,warray->indx+1));
   }

   if (!strcmp("type", comm_set_stp[x].s))
   {
       aux = atoi(args);
       switch(aux)
       {
          case 0:
              stp_data->bpdu_type = BPDU_CONF_STP;
          break;
          
          case 1:
              stp_data->version   = RSTP_VERSION;
              stp_data->bpdu_type = BPDU_CONF_RSTP;
              memcpy((void *)stp_data->rstp_data, (void *)"\x00", 1);
              stp_data->rstp_len  = 1;
          break;
          
          case 2:
              stp_data->bpdu_type = BPDU_TCN;
          break;
          
          default:
                return (command_bad_input(node,warray->indx+1));
          break;
       }
   }

   if (!strcmp("source", comm_set_stp[x].s))
   {
      if ( parser_vrfy_mac(args,stp_data->mac_source) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("dest", comm_set_stp[x].s))
   {
      if ( parser_vrfy_mac(args,stp_data->mac_dest) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("flags", comm_set_stp[x].s))
   {
      parser_str_tolower(args);
      if ( (*args == '0') && (*(args+1) == 'x') && (strlen(args) >= 2) )
      {
          punt = &prova;
          aux = strtol(args, &punt, 16);
          if ( *punt /*|| (aux < 0) || (aux > 255)*/ )
            return (command_bad_input(node,warray->indx+1));
         stp_data->flags |= aux;
      }
      else
      {
         aux = atoi(args);
/*         if ( (aux < 0) || (aux > 255) )
            return (command_bad_input(node,warray->indx+1));*/
         stp_data->flags |= aux;
      }

      return 0;
   }

   if (!strcmp("rootid", comm_set_stp[x].s))
   {
      if (strlen(args) !=  22)
         return (command_bad_input(node,warray->indx+1));

      if ( parser_vrfy_bridge_id(args, stp_data->root_id))
         return (command_bad_input(node,warray->indx+1));

      return 0;
   }
   
   if (!strcmp("cost", comm_set_stp[x].s))
   {
      parser_str_tolower(args);
      if ( (*args == '0') && (*(args+1) == 'x') && (strlen(args) >= 2) )
      {
          punt = &prova;
          aux = strtol(args, &punt, 16);
          if ( *punt /*|| (aux < 0)*/ || (strlen(args) > 10) )
            return (command_bad_input(node,warray->indx+1));
          stp_data->root_pc = aux; 
      }
      else
      {
          aux = atoi(args);
          /*if ( (aux < 0) || (aux > 0xffffffff) )
            return (command_bad_input(node,warray->indx+1));*/
          stp_data->root_pc = aux;
      }
 
      return 0;
   }

   if (!strcmp("bridgeid", comm_set_stp[x].s))
   {
      if (strlen(args) !=  22)
         return (command_bad_input(node,warray->indx+1));

      if ( parser_vrfy_bridge_id(args, stp_data->bridge_id))
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("portid", comm_set_stp[x].s))
   {
      parser_str_tolower(args);
      if ( (*args == '0') && (*(args+1) == 'x') && (strlen(args) >= 2) )
      {
          punt = &prova;
          aux = strtol(args, &punt, 16);
          if ( *punt /*|| (aux < 0) || (aux > 65535)*/ )
            return (command_bad_input(node,warray->indx+1));
          stp_data->port_id = aux;
      }
      else
      {
          aux = atoi(args);
          /*if ( (aux < 0) || (aux > 65535) )
            return (command_bad_input(node,warray->indx+1));*/
          stp_data->port_id = aux;
      }
      
      return 0;
   }

   if (!strcmp("role", comm_set_stp[x].s))
   {
      parser_str_tolower(args);
      if (!strncmp("unknown",args,strlen(args)))
      {
          stp_data->flags |= RSTP_PORT_ROLE_UNKNOWN;
          return 0;
      }
      if (!strncmp("backup",args,strlen(args)))
      {
          stp_data->flags |= RSTP_PORT_ROLE_BACKUP;
          return 0;
      }
      if (!strncmp("root",args,strlen(args)))
      {
          stp_data->flags |= RSTP_PORT_ROLE_ROOT;
          return 0;
      }
      if (!strncmp("designated",args,strlen(args)))
      {
          stp_data->flags |= RSTP_PORT_ROLE_DESIGNATED;
          return 0;
      }
      return (command_bad_input(node,warray->indx+1));
   }
   
   if (!strcmp("state", comm_set_stp[x].s))
   {
      parser_str_tolower(args);
      if (!strncmp("proposal",args,strlen(args)))
      {
          stp_data->flags |= RSTP_PROPOSAL;
          return 0;
      }
      if (!strncmp("learning",args,strlen(args)))
      {
          stp_data->flags |= RSTP_LEARNING;
          return 0;
      }
      if (!strncmp("forwarding",args,strlen(args)))
      {
          stp_data->flags |= RSTP_FORWARDING;
          return 0;
      }
      if (!strncmp("agreement",args,strlen(args)))
      {
          stp_data->flags |= RSTP_AGREEMENT;
          return 0;
      }
      return (command_bad_input(node,warray->indx+1));
   }

   if (!strcmp("message", comm_set_stp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/

      stp_data->message_age = htons(aux * 256);
      return 0;
   }

   if (!strcmp("max-age", comm_set_stp[x].s))
   {
      aux = atoi(args);
      /* if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/

      stp_data->max_age = htons(aux * 256);
      return 0;
   }

   if (!strcmp("hello", comm_set_stp[x].s))
   {
      aux = atoi(args);
      /*if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/
   
      stp_data->hello_time = htons(aux * 256);
      return 0;
   }
   
   if (!strcmp("forward", comm_set_stp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/

      stp_data->forward_delay = htons(aux * 256);
      return 0;
   }
   
   return 0;
}


/*
 * Command set STP defaults
 * No argument needed.
 */
int8_t
command_set_stp_defaults(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128];
   int8_t fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\"\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\"", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   fail = init_attribs(node);

   return fail;
}


/*
 * Command set DTP
 */
int8_t
command_set_dtp(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (help && !params)
      return 0;
    
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"set dtp ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_set_dtp[i].s != NULL)
       {
          if (comm_set_dtp[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_dtp[i].s,comm_set_dtp[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_set_dtp[i].s != NULL)
   {
      if (comm_set_dtp[i].states[node->state])
      {   
         if (!strncmp(comm_set_dtp[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            { 
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_dtp[i].s,comm_set_dtp[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_set_dtp[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = (comm_set_dtp[j].command(node,warray,j,help,help_as_param));
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || ( help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;   
}



/*
 * Command set DTP general
 * All general commands must have just 1 argument...
 */
int8_t
command_set_dtp_general(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128], *args;
   int8_t fail, i, params;
   u_int8_t aux;
   struct dtp_data *dtp_data;
   struct term_vty *vty = node->specific;

   args = warray->word[warray->indx+1];

   if (!args)
      params=0;
   else
      params=1;

   if (warray->nwords > (warray->indx+2))
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\".\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\".", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help && !params)
      return 0;

   if ( (help_as_param && !params) ||
        (help && params) )
   {
      char *string = comm_set_dtp[x].params;
      for(i=0; i<comm_set_dtp[x].nparams; i++)
      {   
          snprintf(msg,sizeof(msg),"  %-30s\r\n",string);
          string+=strlen(string)+1;
          fail = term_vty_write(node,msg,strlen(msg));
          if (fail == -1)
             return -1;
      }
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (help_as_param && (warray->nwords == (warray->indx+2)) )
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (!params)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Incomplete command.");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }
   
   /* Ok, now we have just 1 arg, begin parsing...*/

   dtp_data = node->protocol[PROTO_DTP].tmp_data;
   
   if (!strcmp("interface", comm_set_dtp[x].s))
   {
      int8_t tmp;
      if ((tmp = interfaces_get(args)) == -1)
      {
         fail = command_bad_input(node,warray->indx+1);
         return fail;
      }
       /* Don't repeat interface...*/
      if (!node->used_ints[tmp])
      {
          if ((tmp = interfaces_add(args)) == -1)
          {
             fail = command_bad_input(node,warray->indx+1);
             return fail;
          }
          node->used_ints[tmp] = 1;
      }
      return 0;
   }

   if (!strcmp("version", comm_set_dtp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/
   
      dtp_data->version = aux;
      return 0;
   }

   if (!strcmp("source", comm_set_dtp[x].s))
   {
      if ( parser_vrfy_mac(args,dtp_data->mac_source) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("dest", comm_set_dtp[x].s))
   {
      if ( parser_vrfy_mac(args,dtp_data->mac_dest) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("neighbor", comm_set_dtp[x].s))
   {
      if ( parser_vrfy_mac(args,dtp_data->neighbor) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("domain", comm_set_dtp[x].s))
   {
      if (strlen(args)>DTP_DOMAIN_SIZE)
         return (command_bad_input(node,warray->indx+1));
      strncpy(dtp_data->domain,args,DTP_DOMAIN_SIZE);
      dtp_data->dom_len = strlen(args);
      return 0;
   }
   
   return 0;
}

/*
 * Command set DTP defaults
 * No argument needed.
 */
int8_t
command_set_dtp_defaults(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128];
   int8_t fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\"\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\"", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   /* Ok, now we can set the stp defaults...*/
   
   fail = init_attribs(node);

   return fail;
}


/*
 * Command set DHCP
 */
int8_t
command_set_dhcp(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (help && !params)
      return 0;
    
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"set dhcp ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_set_dhcp[i].s != NULL)
       {
          if (comm_set_dhcp[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_dhcp[i].s,comm_set_dhcp[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_set_dhcp[i].s != NULL)
   {
      if (comm_set_dhcp[i].states[node->state])
      {   
         if (!strncmp(comm_set_dhcp[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            { 
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_dhcp[i].s,comm_set_dhcp[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_set_dhcp[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = (comm_set_dhcp[j].command(node,warray,j,help,help_as_param));
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || ( help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;   
}



/*
 * Command set DHCP general
 * All general commands must have just 1 argument...
 */
int8_t
command_set_dhcp_general(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128], *args;
   int8_t fail, i, params;
   u_int8_t aux;
   struct in_addr addr;
   u_int32_t aux_long;
   struct dhcp_data *dhcp_data;
   struct term_vty *vty = node->specific;

   args = warray->word[warray->indx+1];

   if (!args)
      params=0;
   else
      params=1;

   if (warray->nwords > (warray->indx+2))
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\".\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\".", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help && !params)
      return 0;

   if ( (help_as_param && !params) ||
        (help && params) )
   {
      char *string = comm_set_dhcp[x].params;
      for(i=0; i<comm_set_dhcp[x].nparams; i++)
      {   
          snprintf(msg,sizeof(msg),"  %-30s\r\n",string);
          string+=strlen(string)+1;
          fail = term_vty_write(node,msg,strlen(msg));
          if (fail == -1)
             return -1;
      }
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (help_as_param && (warray->nwords == (warray->indx+2)) )
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (!params)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Incomplete command.");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }
   
   /* Ok, now we have just 1 arg, begin parsing...*/

   dhcp_data = node->protocol[PROTO_DHCP].tmp_data;
   
   if (!strcmp("interface", comm_set_dhcp[x].s))
   {
      int8_t tmp;
      if ((tmp = interfaces_get(args)) == -1)
      {
         fail = command_bad_input(node,warray->indx+1);
         return fail;
      }
       /* Don't repeat interface...*/
      if (!node->used_ints[tmp])
      {
          if ((tmp = interfaces_add(args)) == -1)
          {
             fail = command_bad_input(node,warray->indx+1);
             return fail;
          }
          node->used_ints[tmp] = 1;
      }
      return 0;
   }

   if (!strcmp("opcode", comm_set_dhcp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/
   
      dhcp_data->op = aux;
      return 0;
   }

   if (!strcmp("htype", comm_set_dhcp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/
   
      dhcp_data->htype = aux;
      return 0;
   }

   if (!strcmp("dport", comm_set_dhcp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 65535) )
         return (command_bad_input(node,warray->indx+1));*/
   
      dhcp_data->dport = aux;
      return 0;
   }

   if (!strcmp("sport", comm_set_dhcp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 65535) )
         return (command_bad_input(node,warray->indx+1));*/
   
      dhcp_data->sport = aux;
      return 0;
   }

   if (!strcmp("source", comm_set_dhcp[x].s))
   {
      if ( parser_vrfy_mac(args,dhcp_data->mac_source) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("dest", comm_set_dhcp[x].s))
   {
      if ( parser_vrfy_mac(args,dhcp_data->mac_dest) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("ipsource", comm_set_dhcp[x].s))
   {
      if (parser_get_inet_aton(args, &addr) < 0) 
         return (command_bad_input(node,warray->indx+1));
      aux_long = ntohl(addr.s_addr);
      memcpy((void *)&dhcp_data->sip, (void *)&aux_long, 4);   
      return 0;   
   }

   if (!strcmp("ipdest", comm_set_dhcp[x].s))
   {
      if (parser_get_inet_aton(args, &addr) < 0) 
         return (command_bad_input(node,warray->indx+1));
      aux_long = ntohl(addr.s_addr);
      memcpy((void *)&dhcp_data->dip, (void *)&aux_long, 4);        
      return 0;
   }

   return 0;
}

/*
 * Command set DHCP defaults
 * No argument needed.
 */
int8_t
command_set_dhcp_defaults(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128];
   int8_t fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\"\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\"", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   fail = init_attribs(node);

   return fail;
}



/*
 * Command set VTP
 */
int8_t
command_set_vtp(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (help && !params)
      return 0;
    
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"set vtp ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_set_vtp[i].s != NULL)
       {
          if (comm_set_vtp[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_vtp[i].s,comm_set_vtp[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_set_vtp[i].s != NULL)
   {
      if (comm_set_vtp[i].states[node->state])
      {   
         if (!strncmp(comm_set_vtp[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            { 
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_vtp[i].s,comm_set_vtp[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_set_vtp[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = (comm_set_vtp[j].command(node,warray,j,help,help_as_param));
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || ( help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;   
}



/*
 * Command set VTP general
 * All general commands must have just 1 argument...
 */
int8_t
command_set_vtp_general(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128], *args;
   int8_t fail, i, params;
   u_int32_t aux;
   u_int32_t aux_long;
   struct in_addr addr;
   struct vtp_data *vtp_data;
   struct term_vty *vty = node->specific;

   args = warray->word[warray->indx+1];

   if (!args)
      params=0;
   else
      params=1;

   if (warray->nwords > (warray->indx+2))
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\".\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\".", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help && !params)
      return 0;

   if ( (help_as_param && !params) ||
        (help && params) )
   {
      char *string = comm_set_vtp[x].params;
      for(i=0; i<comm_set_vtp[x].nparams; i++)
      {   
          snprintf(msg,sizeof(msg),"  %-30s\r\n",string);
          string+=strlen(string)+1;
          fail = term_vty_write(node,msg,strlen(msg));
          if (fail == -1)
             return -1;
      }
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (help_as_param && (warray->nwords == (warray->indx+2)) )
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (!params)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Incomplete command.");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }
   
   /* Ok, now we have just 1 arg, begin parsing...*/

   vtp_data = node->protocol[PROTO_VTP].tmp_data;
   
   if (!strcmp("interface", comm_set_vtp[x].s))
   {
      int8_t tmp;
      if ((tmp = interfaces_get(args)) == -1)
      {
         fail = command_bad_input(node,warray->indx+1);
         return fail;
      }
       /* Don't repeat interface...*/
      if (!node->used_ints[tmp])
      {
          if ((tmp = interfaces_add(args)) == -1)
          {
             fail = command_bad_input(node,warray->indx+1);
             return fail;
          }
          node->used_ints[tmp] = 1;
      }
      return 0;
   }

   if (!strcmp("version", comm_set_vtp[x].s))
   {
      aux = atoi(args);
      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));
   
      vtp_data->version = aux;
      return 0;
   }

   if (!strcmp("source", comm_set_vtp[x].s))
   {
      if ( parser_vrfy_mac(args,vtp_data->mac_source) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("dest", comm_set_vtp[x].s))
   {
      if ( parser_vrfy_mac(args,vtp_data->mac_dest) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("code", comm_set_vtp[x].s))
   {
      aux = atol(args);
      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));
      vtp_data->code = aux;
      return 0;
   }

   if (!strcmp("followers", comm_set_vtp[x].s))
   {
      aux = atol(args);
      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));
      vtp_data->followers = aux;
      return 0;
   }

   if (!strcmp("startval", comm_set_vtp[x].s))
   {
      vtp_data->start_val = atol(args);
      return 0;
   }

   if (!strcmp("revision", comm_set_vtp[x].s))
   {
      vtp_data->revision = atol(args);
      return 0;
   }

   if (!strcmp("updater", comm_set_vtp[x].s))
   {
      if (parser_get_inet_aton(args, &addr) < 0) 
         return (command_bad_input(node,warray->indx+1));
      aux_long = ntohl(addr.s_addr);
      memcpy((void *)&vtp_data->updater, (void *)&aux_long, 4);
      return 0;
   }

   return 0;
}

/*
 * Command set VTP defaults
 * No argument needed.
 */
int8_t
command_set_vtp_defaults(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128];
   int8_t fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\"\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\"", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   /* Ok, now we can set the stp defaults...*/
   
   fail = init_attribs(node);

   return fail;
}


/*
 * Command set 802.1Q
 */
int8_t
command_set_dot1q(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (help && !params)
      return 0;
    
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"set dot1q ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_set_dot1q[i].s != NULL)
       {
          if (comm_set_dot1q[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_dot1q[i].s,comm_set_dot1q[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_set_dot1q[i].s != NULL)
   {
      if (comm_set_dot1q[i].states[node->state])
      {   
         if (!strncmp(comm_set_dot1q[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            { 
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_dot1q[i].s,comm_set_dot1q[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_set_dot1q[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = (comm_set_dot1q[j].command(node,warray,j,help,help_as_param));
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || ( help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;   
}



/*
 * Command set 802.1Q general
 * All general commands must have just 1 argument...
 */
int8_t
command_set_dot1q_general(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128], *args;
   int8_t fail, i, params;
   u_int8_t aux;
   int16_t aux16;
   u_int32_t aux_long;
   struct in_addr addr;
   struct dot1q_data *dot1q_data;
   struct term_vty *vty = node->specific;

   args = warray->word[warray->indx+1];

   if (!args)
      params=0;
   else
      params=1;

   if (warray->nwords > (warray->indx+2))
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\".\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\".", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help && !params)
      return 0;

   if ( (help_as_param && !params) ||
        (help && params) )
   {
      char *string = comm_set_dot1q[x].params;
      for(i=0; i<comm_set_dot1q[x].nparams; i++)
      {   
          snprintf(msg,sizeof(msg),"  %-30s\r\n",string);
          string+=strlen(string)+1;
          fail = term_vty_write(node,msg,strlen(msg));
          if (fail == -1)
             return -1;
      }
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (help_as_param && (warray->nwords == (warray->indx+2)) )
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (!params)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Incomplete command.");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }
   
   /* Ok, now we have just 1 arg, begin parsing...*/

   dot1q_data = node->protocol[PROTO_DOT1Q].tmp_data;
   
   if (!strcmp("interface", comm_set_dot1q[x].s))
   {
      int8_t tmp;
      if ((tmp = interfaces_get(args)) == -1)
      {
         fail = command_bad_input(node,warray->indx+1);
         return fail;
      }
       /* Don't repeat interface...*/
      if (!node->used_ints[tmp])
      {
          if ((tmp = interfaces_add(args)) == -1)
          {
             fail = command_bad_input(node,warray->indx+1);
             return fail;
          }
          node->used_ints[tmp] = 1;
      }
      return 0;
   }

   if (!strcmp("priority1", comm_set_dot1q[x].s))
   {
      aux = atoi(args);
      /*if ( (aux < 0)) || (aux > 7) )
         return (command_bad_input(node,warray->indx+1));*/
   
      dot1q_data->priority1 = aux;
      return 0;
   }

   if (!strcmp("priority2", comm_set_dot1q[x].s))
   {
      aux = atoi(args);
      /*if ( (aux < 0) || (aux > 7) )
         return (command_bad_input(node,warray->indx+1));*/
   
      dot1q_data->priority2 = aux;
      return 0;
   }

   if (!strcmp("vlan1", comm_set_dot1q[x].s))
   {
      aux16 = atoi(args);
      if ( (aux16 < 0) || (aux16 > 4095) )
         return (command_bad_input(node,warray->indx+1));
   
      dot1q_data->vlan1 = aux16;
      return 0;
   }

   if (!strcmp("vlan2", comm_set_dot1q[x].s))
   {
      aux16 = atoi(args);
      if ( (aux16 < 0) || (aux16 > 4095) )
         return (command_bad_input(node,warray->indx+1));
   
      dot1q_data->vlan2 = aux16;
      return 0;
   }
   
   if (!strcmp("source", comm_set_dot1q[x].s))
   {
      if ( parser_vrfy_mac(args,dot1q_data->mac_source) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }


   if (!strcmp("ipsource", comm_set_dot1q[x].s))
   {
      if (parser_get_inet_aton(args, &addr) < 0) 
         return (command_bad_input(node,warray->indx+1));
      aux_long = ntohl(addr.s_addr);
      memcpy((void *)&dot1q_data->src_ip, (void *)&aux_long, 4);   
      return 0;   
   }

   if (!strcmp("ipdest", comm_set_dot1q[x].s))
   {
      if (parser_get_inet_aton(args, &addr) < 0) 
         return (command_bad_input(node,warray->indx+1));
      aux_long = ntohl(addr.s_addr);
      memcpy((void *)&dot1q_data->dst_ip, (void *)&aux_long, 4);
      return 0;
   }

   if (!strcmp("dest", comm_set_dot1q[x].s))
   {
      if ( parser_vrfy_mac(args,dot1q_data->mac_dest) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("payload", comm_set_dot1q[x].s))
   {
      if (strlen(args)>MAX_ICMP_PAYLOAD)
         return (command_bad_input(node,warray->indx+1));
      strncpy((char *)dot1q_data->icmp_payload,args,MAX_ICMP_PAYLOAD);
      dot1q_data->icmp_pay_len = strlen(args);
      return 0;
   }
   
   return 0;
}

/*
 * Command set 802.1Q defaults
 * No argument needed.
 */
int8_t
command_set_dot1q_defaults(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128];
   int8_t fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\"\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\"", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   /* Ok, now we can set the stp defaults...*/
   
   fail = init_attribs(node);

   return fail;
}



/*
 * Command set HSRP 
 */
int8_t
command_set_hsrp(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (help && !params)
      return 0;

   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"set hsrp ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_set_hsrp[i].s != NULL)
       {
          if (comm_set_hsrp[i].states[node->state])
          {
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_hsrp[i].s,comm_set_hsrp[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_set_hsrp[i].s != NULL)
   {
      if (comm_set_hsrp[i].states[node->state])
      {
         if (!strncmp(comm_set_hsrp[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            {
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_hsrp[i].s,comm_set_hsrp[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_set_hsrp[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;

   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = (comm_set_hsrp[j].command(node,warray,j,help,help_as_param));
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || ( help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;
}



/*
 * Command set HSRP general
 * All general commands must have just 1 argument...
 */
int8_t
command_set_hsrp_general(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128], *args;
   int8_t fail, i, params;
   u_int8_t aux;
   int32_t aux32;
   struct in_addr addr;
   u_int32_t aux_long;
   struct hsrp_data *hsrp_data;
   struct term_vty *vty = node->specific;

   args = warray->word[warray->indx+1];

   if (!args)
      params=0;
   else
      params=1;

   if (warray->nwords > (warray->indx+2))
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\".\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\".", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }

   if (help && !params)
      return 0;
   if ( (help_as_param && !params) ||
        (help && params) )
   {
      char *string = comm_set_hsrp[x].params;
      for(i=0; i<comm_set_hsrp[x].nparams; i++)
      {   
          snprintf(msg,sizeof(msg),"  %-30s\r\n",string);
          string+=strlen(string)+1;
          fail = term_vty_write(node,msg,strlen(msg));
          if (fail == -1)
             return -1;
      }
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (help_as_param && (warray->nwords == (warray->indx+2)) )
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (!params)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Incomplete command.");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   /* Ok, now we have just 1 arg, begin parsing...*/

   hsrp_data = node->protocol[PROTO_HSRP].tmp_data;

   if (!strcmp("interface", comm_set_hsrp[x].s))
   {
      int8_t tmp;
      if ((tmp = interfaces_get(args)) == -1)
      {
         fail = command_bad_input(node,warray->indx+1);
         return fail;
      }
       /* Don't repeat interface...*/
      if (!node->used_ints[tmp])
      {
          if ((tmp = interfaces_add(args)) == -1)
          {
             fail = command_bad_input(node,warray->indx+1);
             return fail;
          }
          node->used_ints[tmp] = 1;
      }
      return 0;
   }

   if (!strcmp("version", comm_set_hsrp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/

      hsrp_data->version = aux;
      return 0;
   }

   if (!strcmp("opcode", comm_set_hsrp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/

      hsrp_data->opcode = aux;
      return 0;
   }

   if (!strcmp("priority", comm_set_hsrp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/

      hsrp_data->priority = aux;
      return 0;
   }

   if (!strcmp("group", comm_set_hsrp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/

      hsrp_data->group = aux;
      return 0;
   }

   if (!strcmp("hello", comm_set_hsrp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/

      hsrp_data->hello_time = aux;
      return 0;
   }

   if (!strcmp("hold", comm_set_hsrp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/

      hsrp_data->hold_time = aux;
      return 0;
   }

   if (!strcmp("state", comm_set_hsrp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/

      hsrp_data->state = aux;
      return 0;
   }

   if (!strcmp("source", comm_set_hsrp[x].s))
   {
      if ( parser_vrfy_mac(args,hsrp_data->mac_source) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }
   if (!strcmp("dest", comm_set_hsrp[x].s))
   {
      if ( parser_vrfy_mac(args,hsrp_data->mac_dest) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("password", comm_set_hsrp[x].s))
   {
      if (strlen(args)> HSRP_AUTHDATA_LENGTH)
         return (command_bad_input(node,warray->indx+1));
      strncpy(hsrp_data->authdata,args,HSRP_AUTHDATA_LENGTH);
      return 0;
   }

   if (!strcmp("dport", comm_set_dhcp[x].s))
   {
      aux32 = atoi(args);
      if ( (aux32 < 0) || (aux32 > 65535) )
         return (command_bad_input(node,warray->indx+1));
   
      hsrp_data->dport = aux32;
      return 0;
   }

   if (!strcmp("sport", comm_set_dhcp[x].s))
   {
      aux32 = atoi(args);
      if ( (aux32 < 0) || (aux32 > 65535) )
         return (command_bad_input(node,warray->indx+1));
   
      hsrp_data->sport = aux32;
      return 0;
   }

   if (!strcmp("ipsource", comm_set_hsrp[x].s))
   {
      if (parser_get_inet_aton(args, &addr) < 0) 
         return (command_bad_input(node,warray->indx+1));
      aux_long = ntohl(addr.s_addr);
      memcpy((void *)&hsrp_data->sip, (void *)&aux_long, 4);   
      return 0;   
   }

   if (!strcmp("ipdest", comm_set_hsrp[x].s))
   {
      if (parser_get_inet_aton(args, &addr) < 0) 
         return (command_bad_input(node,warray->indx+1));
      aux_long = ntohl(addr.s_addr);
      memcpy((void *)&hsrp_data->dip, (void *)&aux_long, 4);
      return 0;
   }

   if (!strcmp("ipvirtual", comm_set_hsrp[x].s))
   {
      if (parser_get_inet_aton(args, &addr) < 0) 
         return (command_bad_input(node,warray->indx+1));
      aux_long = ntohl(addr.s_addr);
      memcpy((void *)&hsrp_data->virtual_ip, (void *)&aux_long, 4);
      return 0;
   }

   return 0;
}


/*
 * Command set HSRP defaults
 * No argument needed.
 */
int8_t
command_set_hsrp_defaults(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128];
   int8_t fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\"\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\"", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }

   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   /* Ok, now we can set the hsrp defaults...*/

   fail = init_attribs(node);

   return fail;
}


/*
 * Command set CDP
 */
int8_t
command_set_cdp(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (help && !params)
      return 0;
    
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"set cdp ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_set_cdp[i].s != NULL)
       {
          if (comm_set_cdp[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_cdp[i].s,comm_set_cdp[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_set_cdp[i].s != NULL)
   {
      if (comm_set_cdp[i].states[node->state])
      {   
         if (!strncmp(comm_set_cdp[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            { 
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_set_cdp[i].s,comm_set_cdp[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_set_cdp[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = (comm_set_cdp[j].command(node,warray,j,help,help_as_param));
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || ( help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;   
}



/*
 * Command set CDP general
 * All general commands must have just 1 argument...
 */
int8_t
command_set_cdp_general(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128], *args;
   int8_t fail, i, params;
   u_int8_t aux;
   int32_t aux32;
   struct cdp_data *cdp_data;
   struct term_vty *vty = node->specific;

   args = warray->word[warray->indx+1];

   if (!args)
      params=0;
   else
      params=1;

   if (warray->nwords > (warray->indx+2))
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\".\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\".", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help && !params)
      return 0;

   if ( (help_as_param && !params) ||
        (help && params) )
   {
      char *string = comm_set_cdp[x].params;
      for(i=0; i<comm_set_cdp[x].nparams; i++)
      {   
          snprintf(msg,sizeof(msg),"  %-30s\r\n",string);
          string+=strlen(string)+1;
          fail = term_vty_write(node,msg,strlen(msg));
          if (fail == -1)
             return -1;
      }
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (help_as_param && (warray->nwords == (warray->indx+2)) )
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (!params)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Incomplete command.");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }
   
   /* Ok, now we have just 1 arg, begin parsing...*/

   cdp_data = node->protocol[PROTO_CDP].tmp_data;
   
   if (!strcmp("interface", comm_set_cdp[x].s))
   {
      int8_t tmp;
      if ((tmp = interfaces_get(args)) == -1)
      {
         fail = command_bad_input(node,warray->indx+1);
         return fail;
      }
       /* Don't repeat interface...*/
      if (!node->used_ints[tmp])
      {
          if ((tmp = interfaces_add(args)) == -1)
          {
             fail = command_bad_input(node,warray->indx+1);
             return fail;
          }
          node->used_ints[tmp] = 1;
      }
      return 0;
   }

   if (!strcmp("version", comm_set_cdp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/
   
      cdp_data->version = aux;
      return 0;
   }

   if (!strcmp("ttl", comm_set_cdp[x].s))
   {
      aux = atoi(args);
/*      if ( (aux < 0) || (aux > 255) )
         return (command_bad_input(node,warray->indx+1));*/
   
      cdp_data->ttl = aux;
      return 0;
   }

   if (!strcmp("checksum", comm_set_cdp[x].s))
   {
      aux32 = atoi(args);
      if ( (aux32 < 0) || (aux32 > 65535) )
         return (command_bad_input(node,warray->indx+1));
   
      cdp_data->checksum = aux32;
      return 0;
   }

   if (!strcmp("source", comm_set_cdp[x].s))
   {
      if ( parser_vrfy_mac(args,cdp_data->mac_source) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   if (!strcmp("dest", comm_set_cdp[x].s))
   {
      if ( parser_vrfy_mac(args,cdp_data->mac_dest) )
         return (command_bad_input(node,warray->indx+1));
      return 0;
   }

   return 0;
}


/*
 * Command set CDP defaults
 * No argument needed.
 */
int8_t
command_set_cdp_defaults(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   char msg[128];
   int8_t fail;
   struct term_vty *vty = node->specific;

   if (warray->word[warray->indx+1])
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments:  \"%s\"\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments:  \"%s\"", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help)
      return 0;

   if (help_as_param)
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   fail = init_attribs(node);

   return fail;
}



/*
 * Command run...
 */
int8_t
command_run(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;
      
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"run ?\" for a list of subcommands");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_run[i].s != NULL)
       {
          if (comm_run[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_run[i].s,comm_run[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_run[i].s != NULL)
   {
      if (comm_run[i].states[node->state])
      {   
         if (!strncmp(comm_run[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2] )   )
            {
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_run[i].s,comm_run[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_run[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);

      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = command_run_proto(node,warray,j,help,help_as_param,comm_run[j].proto);
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || (help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help || help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;
}




int8_t
command_run_proto(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param,
                   u_int8_t proto)
{
   int8_t gotit;
   char msg[128];
   int8_t fail, i, j, params;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (help && !params)
      return 0;
    
   if (!params && !help && !help_as_param)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Type \"run %s ?\" for a list of subcommands",warray->word[warray->indx]);
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   i = j = gotit = 0;

   if (help_as_param && !params)
   {
       fail = i = j = gotit = 0;

       while(comm_run_proto[i].s != NULL)
       {
          if (comm_run_proto[i].states[node->state])
          {   
              snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_run_proto[i].s,comm_run_proto[i].help);
              fail = term_vty_write(node,msg,strlen(msg));
              if (fail == -1)
                 return -1;
          }
          i++;
       }
       return fail;
   }

   while(comm_run_proto[i].s != NULL)
   {
      if (comm_run_proto[i].states[node->state])
      {   
         if (!strncmp(comm_run_proto[i].s, warray->word[warray->indx+1], strlen(warray->word[warray->indx+1])))
         {
            if ( (help && !params) || (help && params && !warray->word[warray->indx+2]) )
            { 
               snprintf(msg,sizeof(msg),"  %-10s %-30s\r\n",comm_run_proto[i].s,comm_run_proto[i].help);
               fail = term_vty_write(node,msg,strlen(msg));
               if ( fail == -1)
                  return -1;
            }
            if (strlen(warray->word[warray->indx+1]) == strlen(comm_run_proto[i].s))
            {
               gotit=1;
               j=i;
               break;
            }
            if (!j) j=i;
            gotit++;
         }
      }
      i++;
   }

   fail = 0;
   
   if (!gotit)
   {
      if (help || help_as_param)
      {
         snprintf(msg,sizeof(msg),"%% Unrecognized command:  \"%s\"\r\n",vty->buf_command);
         fail = term_vty_write(node,msg, strlen(msg));
      }
      else
         fail = command_bad_input(node,warray->indx+1);
      
      vty->repeat_command = 1;   
   }
   else
   {
      if (gotit==1) /* Ok, execute command...*/
      {
         if (!help || (help && params) )
         {
            warray->indx++;
            fail = command_run_proto2(node,warray,j,help,help_as_param,proto);
         }
         vty->repeat_command= 1;
      }
      else /* More than 1 matching command...*/
      {
         if ( (!help && !help_as_param) || ( help_as_param && params))
         {
            vty->repeat_command= 0;
            if (help_as_param)
               snprintf(msg,sizeof(msg),"%% Ambiguous command:  \"%s\"\r\n", vty->buf_command);
            else
               snprintf(msg,sizeof(msg),"\r\n%% Ambiguous command:  \"%s\"", vty->buf_command);
            fail = term_vty_write(node,msg, strlen(msg));
         }
         else
         {
            if ( (help || help_as_param) && !params)
               vty->repeat_command= 1;
         }
      }
   }

   return fail;

}



/*
 * Command run proto attack
 */
int8_t
command_run_proto2(struct term_node *node, struct words_array *warray, int16_t x, int8_t help, int8_t help_as_param,
                    u_int8_t proto)
{
   char msg[128];
   int8_t i, fail, params, aux;
   struct attack *theattack = NULL;
   struct term_vty *vty = node->specific;

   if (!(warray->word[warray->indx+1]))
      params=0;
   else
      params=1;

   if (warray->nwords > (warray->indx+2))
   {
       if (help || help_as_param)
          snprintf(msg,sizeof(msg),"%% Too many arguments: \"%s\".\r\n", vty->buf_command);
       else
          snprintf(msg,sizeof(msg),"\r\n%% Too many arguments: \"%s\".", vty->buf_command);
       fail = term_vty_write(node,msg, strlen(msg));
       return fail;
   }   

   if (help && !params)
      return 0;

   if ( (help_as_param && !params) ||
        (help && params) )
   {
      theattack = protocols[proto].attacks;
      i=0;
      while(theattack[i].s != NULL)
      {
          snprintf(msg,sizeof(msg),"  <%d>   %s attack %s\r\n", i, 
                    (theattack[i].type == DOS) ? "DOS" : "NONDOS",
                       theattack[i].s);
          fail = term_vty_write(node,msg,strlen(msg));
          if (fail == -1)
             return -1;
          i++;
      }
             
      snprintf(msg,sizeof(msg),"  <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   if (!params)
   {
      snprintf(msg,sizeof(msg),"\r\n%% Incomplete command.");
      fail = term_vty_write(node,msg, strlen(msg));
      return fail;
   }

   if (help_as_param && (warray->nwords == (warray->indx+2)) )
   {
      snprintf(msg,sizeof(msg),"   <cr>\r\n");
      fail = term_vty_write(node,msg,strlen(msg));
      return fail;
   }

   /* Ok, now we have just 1 arg, begin parsing...*/
   aux = atoi(warray->word[warray->indx+1]);

    /* Dirty trick to take the max attack number... 
     * Man, i'm now in the plane flying to Madrid with
     * Ramon so don't be cruel! */
    theattack = protocols[proto].attacks;
    i=0;
    while(theattack[i].s != NULL)
        i++;
   
   if ( (aux < 0) || (aux > (i-1)) )
      return (command_bad_input(node,warray->indx+1));

   /* Ok, launch attack, plz...*/
   
   return (command_run_generic_attack(node, proto, aux));
}


int8_t
command_run_generic_attack(struct term_node *node, u_int8_t proto, int8_t aux)
{
   char msg[128];
   int8_t fail=1, i;
   struct attack_param *attack_param = NULL;
   struct attack *theattack = NULL;
   struct term_vty *vty = node->specific;

   for (i=0; i< MAX_INTERFACES; i++)
   {
      if (node->used_ints[i])
      {
         fail=0;
         break;
      }
   }

   if (fail)
   {
       snprintf(msg,sizeof(msg),"\r\n%% Network interface not specified. Attack aborted.");
       fail = term_vty_write(node, msg, strlen(msg));
       return fail;
   }
   
   theattack = protocols[proto].attacks;
   
   if (theattack[aux].nparams) /* Do we need parameters for attack? */
   {
       if ((attack_param = calloc(1,
                  (sizeof(struct attack_param) * theattack[aux].nparams))) == NULL)
       {
          thread_error(" command_run_generic_attack calloc",errno);
          return -1;
       }
       memcpy( attack_param, (void *)(theattack[aux].param),
               sizeof(struct attack_param) * theattack[aux].nparams);
       if (attack_init_params(node, attack_param, theattack[aux].nparams) < 0)
       {
          free(attack_param);
          return -1;
       }
       vty->substate = 0;
       vty->nparams = theattack[aux].nparams;
       vty->attack_param = attack_param;
       vty->attack_proto = proto;
       vty->attack_index = aux;
       node->state = PARAMS_STATE;
   }
   else
      attack_launch(node, proto, aux, NULL, 0);
   
   return 0;
}





int8_t
command_bad_input(struct term_node *node, int8_t badindex)
{
   char msg[128], *begin=NULL, *marker;
   int8_t fail, i, j, spaces, indx=0;
   struct term_vty *vty = node->specific;
   
   for(i=0;i<vty->command_len;i++)
   {
      if (*(vty->buf_command+i) != SPACE)
      {
         begin = vty->buf_command+i;
         j=0;
         while( (*(begin+j)!=SPACE) && *(begin+j))
           j++;
         if (indx == badindex) /* Gotit!!*/
            break;
         indx++;
         i+=j;
      }
   }
      
   if (term_vty_write(node,"\r\n", 2) < 0)
      return -1;
   
   /* Now the spaces...*/
   spaces = strlen(term_states[node->state].prompt2) + (begin-vty->buf_command);

   marker = (char *)calloc(1,(spaces+2));
   if ( marker == NULL)
      return -1;
   
   memset(marker,SPACE,spaces);
   
   *(marker+spaces) = '^';
      
   if (term_vty_write(node,marker,spaces+1) < 0)
   {
      free(marker);
      return -1;
   }
   
   snprintf(msg,sizeof(msg),"\r\n%% Invalid input detected at '^' marker.\r\n");
   
   fail = term_vty_write(node,msg, strlen(msg));
   
   free(marker);
   
   return fail;         
}

/* vim:set tabstop=4:set expandtab:set shiftwidth=4:set textwidth=78: */

Generated by  Doxygen 1.6.0   Back to index