blob: 7dff714ca3b28dfdc073da004d2c464ad060d246 [file] [log] [blame]
/**
* \addtogroup telnetd
* @{
*/
/**
* \file
* An example telnet server shell
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the Contiki desktop OS.
*
* $Id: telnetd-shell.c,v 1.1.2.1 2003/10/06 22:56:22 adam Exp $
*
*/
#include "uip.h"
#include "telnetd.h"
#include <string.h>
struct ptentry {
char c;
void (* pfunc)(struct telnetd_state *s, char *str);
};
/*-----------------------------------------------------------------------------------*/
static void
parse(struct telnetd_state *s, register char *str, struct ptentry *t)
{
register struct ptentry *p;
char *sstr;
sstr = str;
/* Loop over the parse table entries in t in order to find one that
matches the first character in str. */
for(p = t; p->c != 0; ++p) {
if(*str == p->c) {
/* Skip rest of the characters up to the first space. */
while(*str != ' ') {
++str;
}
/* Skip all spaces.*/
while(*str == ' ') {
++str;
}
/* Call parse table entry function and return. */
p->pfunc(s, str);
return;
}
}
/* Did not find matching entry in parse table. We just call the
default handler supplied by the caller and return. */
p->pfunc(s, str);
}
/*-----------------------------------------------------------------------------------*/
static void
exitt(struct telnetd_state *s, char *str)
{
telnetd_close(s);
}
/*-----------------------------------------------------------------------------------*/
static void
inttostr(register char *str, unsigned int i)
{
str[0] = '0' + i / 100;
if(str[0] == '0') {
str[0] = ' ';
}
str[1] = '0' + (i / 10) % 10;
if(str[1] == '0') {
str[1] = ' ';
}
str[2] = '0' + i % 10;
str[3] = ' ';
str[4] = 0;
}
/*-----------------------------------------------------------------------------------*/
static void
stats(struct telnetd_state *s, char *strr)
{
char str[10];
inttostr(str, uip_stat.ip.recv);
telnetd_output(s, "IP packets received ", str);
inttostr(str, uip_stat.ip.sent);
telnetd_output(s, "IP packets sent ", str);
inttostr(str, uip_stat.ip.drop);
telnetd_output(s, "IP packets dropped ", str);
inttostr(str, uip_stat.icmp.recv);
telnetd_output(s, "ICMP packets received ", str);
inttostr(str, uip_stat.icmp.sent);
telnetd_output(s, "ICMP packets sent ", str);
inttostr(str, uip_stat.icmp.drop);
telnetd_output(s, "ICMP packets dropped ", str);
inttostr(str, uip_stat.tcp.recv);
telnetd_output(s, "TCP packets received ", str);
inttostr(str, uip_stat.tcp.sent);
telnetd_output(s, "TCP packets sent ", str);
inttostr(str, uip_stat.tcp.drop);
telnetd_output(s, "TCP packets dropped ", str);
inttostr(str, uip_stat.tcp.rexmit);
telnetd_output(s, "TCP packets retransmitted ", str);
inttostr(str, uip_stat.tcp.synrst);
telnetd_output(s, "TCP connection attempts ", str);
}
/*-----------------------------------------------------------------------------------*/
static void
help(struct telnetd_state *s, char *str)
{
telnetd_output(s, "Available commands:", "");
telnetd_output(s, "stats - show uIP statistics", "");
telnetd_output(s, "exit - exit shell", "");
telnetd_output(s, "? - show this help", "");
}
/*-----------------------------------------------------------------------------------*/
static void
none(struct telnetd_state *s, char *str)
{
if(strlen(str) > 0) {
telnetd_output(s, "Unknown command", "");
}
}
/*-----------------------------------------------------------------------------------*/
static struct ptentry configparsetab[] =
{{'s', stats},
{'e', exitt},
{'?', help},
/* Default action */
{0, none}};
/*-----------------------------------------------------------------------------------*/
void
telnetd_connected(struct telnetd_state *s)
{
telnetd_output(s, "uIP command shell", "");
telnetd_output(s, "Type '?' for help", "");
telnetd_prompt(s, "uIP-0.9> ");
}
/*-----------------------------------------------------------------------------------*/
void
telnetd_input(struct telnetd_state *s, char *cmd)
{
parse(s, cmd, configparsetab);
telnetd_prompt(s, "uIP-0.9> ");
}
/*-----------------------------------------------------------------------------------*/