OpenCores
URL https://opencores.org/ocsvn/igor/igor/trunk

Subversion Repositories igor

[/] [igor/] [trunk/] [avr/] [eth-test/] [uip/] [telnetd.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 atypic
/*
2
 * Copyright (c) 2003, Adam Dunkels.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. The name of the author may not be used to endorse or promote
14
 *    products derived from this software without specific prior
15
 *    written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * This file is part of the uIP TCP/IP stack
30
 *
31
 * $Id: telnetd.c,v 1.2 2006/06/07 09:43:54 adam Exp $
32
 *
33
 */
34
 
35
#include "uip.h"
36
#include "telnetd.h"
37
#include "memb.h"
38
#include "shell.h"
39
 
40
#include <string.h>
41
 
42
#define ISO_nl       0x0a
43
#define ISO_cr       0x0d
44
 
45
struct telnetd_line {
46
  char line[TELNETD_CONF_LINELEN];
47
};
48
MEMB(linemem, struct telnetd_line, TELNETD_CONF_NUMLINES);
49
 
50
#define STATE_NORMAL 0
51
#define STATE_IAC    1
52
#define STATE_WILL   2
53
#define STATE_WONT   3
54
#define STATE_DO     4
55
#define STATE_DONT   5
56
#define STATE_CLOSE  6
57
 
58
static struct telnetd_state s;
59
 
60
#define TELNET_IAC   255
61
#define TELNET_WILL  251
62
#define TELNET_WONT  252
63
#define TELNET_DO    253
64
#define TELNET_DONT  254
65
 
66
/*---------------------------------------------------------------------------*/
67
static char *
68
alloc_line(void)
69
{
70
  return memb_alloc(&linemem);
71
}
72
/*---------------------------------------------------------------------------*/
73
static void
74
dealloc_line(char *line)
75
{
76
  memb_free(&linemem, line);
77
}
78
/*---------------------------------------------------------------------------*/
79
void
80
shell_quit(char *str)
81
{
82
  s.state = STATE_CLOSE;
83
}
84
/*---------------------------------------------------------------------------*/
85
static void
86
sendline(char *line)
87
{
88
  static unsigned int i;
89
 
90
  for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
91
    if(s.lines[i] == NULL) {
92
      s.lines[i] = line;
93
      break;
94
    }
95
  }
96
  if(i == TELNETD_CONF_NUMLINES) {
97
    dealloc_line(line);
98
  }
99
}
100
/*---------------------------------------------------------------------------*/
101
void
102
shell_prompt(char *str)
103
{
104
  char *line;
105
  line = alloc_line();
106
  if(line != NULL) {
107
    strncpy(line, str, TELNETD_CONF_LINELEN);
108
    /*    petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/
109
    sendline(line);
110
  }
111
}
112
/*---------------------------------------------------------------------------*/
113
void
114
shell_output(char *str1, char *str2)
115
{
116
  static unsigned len;
117
  char *line;
118
 
119
  line = alloc_line();
120
  if(line != NULL) {
121
    len = strlen(str1);
122
    strncpy(line, str1, TELNETD_CONF_LINELEN);
123
    if(len < TELNETD_CONF_LINELEN) {
124
      strncpy(line + len, str2, TELNETD_CONF_LINELEN - len);
125
    }
126
    len = strlen(line);
127
    if(len < TELNETD_CONF_LINELEN - 2) {
128
      line[len] = ISO_cr;
129
      line[len+1] = ISO_nl;
130
      line[len+2] = 0;
131
    }
132
    /*    petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/
133
    sendline(line);
134
  }
135
}
136
/*---------------------------------------------------------------------------*/
137
void
138
telnetd_init(void)
139
{
140
  uip_listen(HTONS(23));
141
  memb_init(&linemem);
142
  shell_init();
143
}
144
/*---------------------------------------------------------------------------*/
145
static void
146
acked(void)
147
{
148
  static unsigned int i;
149
 
150
  while(s.numsent > 0) {
151
    dealloc_line(s.lines[0]);
152
    for(i = 1; i < TELNETD_CONF_NUMLINES; ++i) {
153
      s.lines[i - 1] = s.lines[i];
154
    }
155
    s.lines[TELNETD_CONF_NUMLINES - 1] = NULL;
156
    --s.numsent;
157
  }
158
}
159
/*---------------------------------------------------------------------------*/
160
static void
161
senddata(void)
162
{
163
  static char *bufptr, *lineptr;
164
  static int buflen, linelen;
165
 
166
  bufptr = uip_appdata;
167
  buflen = 0;
168
  for(s.numsent = 0; s.numsent < TELNETD_CONF_NUMLINES &&
169
        s.lines[s.numsent] != NULL ; ++s.numsent) {
170
    lineptr = s.lines[s.numsent];
171
    linelen = strlen(lineptr);
172
    if(linelen > TELNETD_CONF_LINELEN) {
173
      linelen = TELNETD_CONF_LINELEN;
174
    }
175
    if(buflen + linelen < uip_mss()) {
176
      memcpy(bufptr, lineptr, linelen);
177
      bufptr += linelen;
178
      buflen += linelen;
179
    } else {
180
      break;
181
    }
182
  }
183
  uip_send(uip_appdata, buflen);
184
}
185
/*---------------------------------------------------------------------------*/
186
static void
187
closed(void)
188
{
189
  static unsigned int i;
190
 
191
  for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
192
    if(s.lines[i] != NULL) {
193
      dealloc_line(s.lines[i]);
194
    }
195
  }
196
}
197
/*---------------------------------------------------------------------------*/
198
static void
199
get_char(u8_t c)
200
{
201
  if(c == ISO_cr) {
202
    return;
203
  }
204
 
205
  s.buf[(int)s.bufptr] = c;
206
  if(s.buf[(int)s.bufptr] == ISO_nl ||
207
     s.bufptr == sizeof(s.buf) - 1) {
208
    if(s.bufptr > 0) {
209
      s.buf[(int)s.bufptr] = 0;
210
      /*      petsciiconv_topetscii(s.buf, TELNETD_CONF_LINELEN);*/
211
    }
212
    shell_input(s.buf);
213
    s.bufptr = 0;
214
  } else {
215
    ++s.bufptr;
216
  }
217
}
218
/*---------------------------------------------------------------------------*/
219
static void
220
sendopt(u8_t option, u8_t value)
221
{
222
  char *line;
223
  line = alloc_line();
224
  if(line != NULL) {
225
    line[0] = TELNET_IAC;
226
    line[1] = option;
227
    line[2] = value;
228
    line[3] = 0;
229
    sendline(line);
230
  }
231
}
232
/*---------------------------------------------------------------------------*/
233
static void
234
newdata(void)
235
{
236
  u16_t len;
237
  u8_t c;
238
  char *dataptr;
239
 
240
 
241
  len = uip_datalen();
242
  dataptr = (char *)uip_appdata;
243
 
244
  while(len > 0 && s.bufptr < sizeof(s.buf)) {
245
    c = *dataptr;
246
    ++dataptr;
247
    --len;
248
    switch(s.state) {
249
    case STATE_IAC:
250
      if(c == TELNET_IAC) {
251
        get_char(c);
252
        s.state = STATE_NORMAL;
253
      } else {
254
        switch(c) {
255
        case TELNET_WILL:
256
          s.state = STATE_WILL;
257
          break;
258
        case TELNET_WONT:
259
          s.state = STATE_WONT;
260
          break;
261
        case TELNET_DO:
262
          s.state = STATE_DO;
263
          break;
264
        case TELNET_DONT:
265
          s.state = STATE_DONT;
266
          break;
267
        default:
268
          s.state = STATE_NORMAL;
269
          break;
270
        }
271
      }
272
      break;
273
    case STATE_WILL:
274
      /* Reply with a DONT */
275
      sendopt(TELNET_DONT, c);
276
      s.state = STATE_NORMAL;
277
      break;
278
 
279
    case STATE_WONT:
280
      /* Reply with a DONT */
281
      sendopt(TELNET_DONT, c);
282
      s.state = STATE_NORMAL;
283
      break;
284
    case STATE_DO:
285
      /* Reply with a WONT */
286
      sendopt(TELNET_WONT, c);
287
      s.state = STATE_NORMAL;
288
      break;
289
    case STATE_DONT:
290
      /* Reply with a WONT */
291
      sendopt(TELNET_WONT, c);
292
      s.state = STATE_NORMAL;
293
      break;
294
    case STATE_NORMAL:
295
      if(c == TELNET_IAC) {
296
        s.state = STATE_IAC;
297
      } else {
298
        get_char(c);
299
      }
300
      break;
301
    }
302
 
303
 
304
  }
305
 
306
}
307
/*---------------------------------------------------------------------------*/
308
void
309
telnetd_appcall(void)
310
{
311
  static unsigned int i;
312
  if(uip_connected()) {
313
    /*    tcp_markconn(uip_conn, &s);*/
314
    for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
315
      s.lines[i] = NULL;
316
    }
317
    s.bufptr = 0;
318
    s.state = STATE_NORMAL;
319
 
320
    shell_start();
321
  }
322
 
323
  if(s.state == STATE_CLOSE) {
324
    s.state = STATE_NORMAL;
325
    uip_close();
326
    return;
327
  }
328
 
329
  if(uip_closed() ||
330
     uip_aborted() ||
331
     uip_timedout()) {
332
    closed();
333
  }
334
 
335
  if(uip_acked()) {
336
    acked();
337
  }
338
 
339
  if(uip_newdata()) {
340
    newdata();
341
  }
342
 
343
  if(uip_rexmit() ||
344
     uip_newdata() ||
345
     uip_acked() ||
346
     uip_connected() ||
347
     uip_poll()) {
348
    senddata();
349
  }
350
}
351
/*---------------------------------------------------------------------------*/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.