Skip to content

Commit af8f3f7

Browse files
committed
TELNET server and client.
1 parent 6363ea1 commit af8f3f7

File tree

5 files changed

+285
-1
lines changed

5 files changed

+285
-1
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ src/libncp.a
55
src/ping
66
src/finger
77
src/finser
8+
src/telnet
9+
src/telser
810
test/*.log

src/Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CFLAGS=-g -Wall
22

33
NCP=-L. -lncp
44

5-
all: ncp ping finger finser
5+
all: ncp ping finger finser telnet telser
66

77
ncp: ncp.o imp.o
88

@@ -18,3 +18,11 @@ finger: finger.o libncp.a
1818

1919
finser: finser.o libncp.a
2020
$(CC) -o $@ $< $(NCP)
21+
22+
telnet: telnet.o libncp.a
23+
$(CC) -o $@ $< $(NCP)
24+
25+
telser: telser.o libncp.a
26+
$(CC) -o $@ $< $(NCP)
27+
28+
telnet.o telser.o:: telnet.h

src/telnet.c

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
#include <stdio.h>
2+
#include <errno.h>
3+
#include <stdlib.h>
4+
#include <unistd.h>
5+
#include <string.h>
6+
#include "ncp.h"
7+
#include "telnet.h"
8+
9+
static void option (unsigned char c)
10+
{
11+
switch (c) {
12+
case OPT_BINARY:
13+
fprintf (stderr, "[Binary Transmission]");
14+
break;
15+
case OPT_ECHO:
16+
fprintf (stderr, "[Echo]");
17+
break;
18+
case OPT_RECONNECTION:
19+
fprintf (stderr, "[Reconnection]");
20+
break;
21+
case OPT_SUPPRESS_GO_AHEAD:
22+
fprintf (stderr, "[Suppress Go Ahead]");
23+
break;
24+
case OPT_APPROX_MSG_SIZE:
25+
fprintf (stderr, "[Approx Message Size Negotiation]");
26+
break;
27+
case OPT_STATUS:
28+
fprintf (stderr, "[Status]");
29+
break;
30+
case OPT_TIMING_MARK:
31+
fprintf (stderr, "[Timing Mark]");
32+
break;
33+
case OPT_REMOTE_CTRL_TANDE:
34+
fprintf (stderr, "[Remote Controlled Trans and Echo]");
35+
break;
36+
case OPT_EXTENDED_ASCII:
37+
fprintf (stderr, "[Extended Ascii]");
38+
break;
39+
case OPT_SUPDUP:
40+
fprintf (stderr, "[Supdup]");
41+
break;
42+
case OPT_SUPDUP_OUTPUT:
43+
fprintf (stderr, "[Supdup Output]");
44+
break;
45+
default:
46+
fprintf (stderr, "[Unknown Option]");
47+
break;
48+
}
49+
}
50+
51+
static int special (unsigned char c, const unsigned char *data)
52+
{
53+
switch (c) {
54+
case IAC:
55+
write (1, &c, 1);
56+
return 0;
57+
case DONT:
58+
fprintf (stderr, "[DONT]");
59+
option (*data);
60+
return 1;
61+
case DO:
62+
fprintf (stderr, "[DO]");
63+
option (*data);
64+
return 1;
65+
case WONT:
66+
fprintf (stderr, "[WONT]");
67+
option (*data);
68+
return 1;
69+
case WILL:
70+
fprintf (stderr, "[WILL]");
71+
option (*data);
72+
return 1;
73+
case SB:
74+
fprintf (stderr, "[SB]");
75+
return 0;
76+
case GA:
77+
fprintf (stderr, "[GA]");
78+
return 0;
79+
case EL:
80+
fprintf (stderr, "[EL]");
81+
return 0;
82+
case EC:
83+
fprintf (stderr, "[EC]");
84+
write (1, "\b \b", 3);
85+
return 0;
86+
case AYT:
87+
fprintf (stderr, "[AYT]");
88+
return 0;
89+
case AO:
90+
fprintf (stderr, "[AO]");
91+
return 0;
92+
case IP:
93+
fprintf (stderr, "[IP]");
94+
return 0;
95+
case BRK:
96+
fprintf (stderr, "[BRK]");
97+
return 0;
98+
case MARK:
99+
fprintf (stderr, "[MARK]");
100+
return 0;
101+
case NOP:
102+
fprintf (stderr, "[NOP]");
103+
return 0;
104+
case SE:
105+
fprintf (stderr, "[SE]");
106+
return 0;
107+
default:
108+
fprintf (stderr, "[Unknown Option]");
109+
return 0;
110+
}
111+
}
112+
113+
static void process (const unsigned char *data, int size)
114+
{
115+
int i;
116+
117+
for (i = 0; i < size; i++)
118+
fprintf(stderr, "{%03o}", data[i]);
119+
fprintf(stderr, "\n");
120+
121+
for (i = 0; i < size; i++) {
122+
switch (data[i]) {
123+
case NUL:
124+
break;
125+
case IAC:
126+
i += special (data[i+1], &data[i+2]);
127+
break;
128+
default:
129+
write (1, &data[i], 1);
130+
break;
131+
}
132+
}
133+
}
134+
135+
int main (int argc, char **argv)
136+
{
137+
char options[] = {
138+
IAC, DO, OPT_ECHO,
139+
IAC, DO, OPT_SUPPRESS_GO_AHEAD,
140+
IAC, WILL, OPT_SUPPRESS_GO_AHEAD,
141+
0
142+
};
143+
unsigned char reply[1000];
144+
int host, connection, size;
145+
146+
if (argc != 2) {
147+
fprintf (stderr, "Usage: %s host\n", argv[0]);
148+
exit (1);
149+
}
150+
151+
host = atoi (argv[1]);
152+
153+
if (ncp_init (NULL) == -1) {
154+
fprintf (stderr, "NCP initializtion error: %s.\n", strerror (errno));
155+
if (errno == ECONNREFUSED)
156+
fprintf (stderr, "Is the NCP server started?\n");
157+
exit (1);
158+
}
159+
160+
printf ("TELNET to host %03o.\n", host);
161+
162+
switch (ncp_open (host, 23, &connection)) {
163+
case 0:
164+
break;
165+
case -1:
166+
default:
167+
fprintf (stderr, "NCP open error.\n");
168+
exit (1);
169+
case -2:
170+
fprintf (stderr, "Open refused.\n");
171+
exit (1);
172+
}
173+
174+
if (ncp_write (connection, options, strlen (options)) == -1) {
175+
fprintf (stderr, "NCP write error.\n");
176+
exit (1);
177+
}
178+
179+
size = sizeof reply;
180+
if (ncp_read (connection, reply, &size) == -1) {
181+
fprintf (stderr, "NCP read error.\n");
182+
exit (1);
183+
}
184+
185+
process (reply, size);
186+
187+
if (ncp_close (connection) == -1) {
188+
fprintf (stderr, "NCP close error.\n");
189+
exit (1);
190+
}
191+
}

src/telnet.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#define IAC 0377
2+
#define DONT 0376
3+
#define DO 0375
4+
#define WONT 0374
5+
#define WILL 0373
6+
#define SB 0372
7+
#define GA 0371
8+
#define EL 0370
9+
#define EC 0367
10+
#define AYT 0366
11+
#define AO 0365
12+
#define IP 0364
13+
#define BRK 0363
14+
#define MARK 0362
15+
#define NOP 0361
16+
#define SE 0360
17+
#define NUL 0000
18+
19+
#define OPT_BINARY 000
20+
#define OPT_ECHO 001
21+
#define OPT_RECONNECTION 002
22+
#define OPT_SUPPRESS_GO_AHEAD 003
23+
#define OPT_APPROX_MSG_SIZE 004
24+
#define OPT_STATUS 005
25+
#define OPT_TIMING_MARK 006
26+
#define OPT_REMOTE_CTRL_TANDE 007
27+
#define OPT_EXTENDED_ASCII 021
28+
#define OPT_SUPDUP 025
29+
#define OPT_SUPDUP_OUTPUT 026

src/telser.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include <stdio.h>
2+
#include <errno.h>
3+
#include <stdlib.h>
4+
#include <unistd.h>
5+
#include <string.h>
6+
#include "ncp.h"
7+
#include "telnet.h"
8+
9+
int main (int argc, char **argv)
10+
{
11+
int sock = 23;
12+
char options[] = {
13+
IAC, DO, OPT_ECHO,
14+
IAC, DO, OPT_SUPPRESS_GO_AHEAD,
15+
IAC, WILL, OPT_SUPPRESS_GO_AHEAD,
16+
0
17+
};
18+
char *banner;
19+
int host, connection;
20+
21+
if (argc != 1) {
22+
fprintf (stderr, "Usage: %s\n", argv[0]);
23+
exit (1);
24+
}
25+
26+
if (ncp_init (NULL) == -1) {
27+
fprintf (stderr, "NCP initializtion error: %s.\n", strerror (errno));
28+
if (errno == ECONNREFUSED)
29+
fprintf (stderr, "Is the NCP server started?\n");
30+
exit (1);
31+
}
32+
33+
if (ncp_listen (sock, &host, &connection) == -1) {
34+
fprintf (stderr, "NCP listen error.\n");
35+
exit (1);
36+
}
37+
38+
if (ncp_write (connection, options, strlen (options)) == -1) {
39+
fprintf (stderr, "NCP write error.\n");
40+
exit (1);
41+
}
42+
43+
banner = "Welcome to Unix.\r\n";
44+
if (ncp_write (connection, banner, strlen (banner)) == -1) {
45+
fprintf (stderr, "NCP write error.\n");
46+
exit (1);
47+
}
48+
49+
if (ncp_close (connection) == -1) {
50+
fprintf (stderr, "NCP close error.\n");
51+
exit (1);
52+
}
53+
54+
}

0 commit comments

Comments
 (0)