This is a simple telnet client written in C. In the negotiation phase of the connection it will respond with WONT to any DO coming from the server, and it will encourage the server to DO anything it offers with WILL. The only exception is the screen size setting, advertised as 24 x 80 by the client.
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <termios.h> #include <fcntl.h> #define DO 0xfd #define WONT 0xfc #define WILL 0xfb #define DONT 0xfe #define CMD 0xff #define CMD_ECHO 1 #define CMD_WINDOW_SIZE 31 void negotiate(int sock, unsigned char *buf, int len) { int i; if (buf[1] == DO && buf[2] == CMD_WINDOW_SIZE) { unsigned char tmp1[10] = {255, 251, 31}; if (send(sock, tmp1, 3 , 0) < 0) exit(1); unsigned char tmp2[10] = {255, 250, 31, 0, 80, 0, 24, 255, 240}; if (send(sock, tmp2, 9, 0) < 0) exit(1); return; } for (i = 0; i < len; i++) { if (buf[i] == DO) buf[i] = WONT; else if (buf[i] == WILL) buf[i] = DO; } if (send(sock, buf, len , 0) < 0) exit(1); } static struct termios tin; static void terminal_set(void) { // save terminal configuration tcgetattr(STDIN_FILENO, &tin); static struct termios tlocal; memcpy(&tlocal, &tin, sizeof(tin)); cfmakeraw(&tlocal); tcsetattr(STDIN_FILENO,TCSANOW,&tlocal); } static void terminal_reset(void) { // restore terminal upon exit tcsetattr(STDIN_FILENO,TCSANOW,&tin); } #define BUFLEN 20 int main(int argc , char *argv[]) { int sock; struct sockaddr_in server; unsigned char buf[BUFLEN + 1]; int len; int i; if (argc < 2 || argc > 3) { printf("Usage: %s address [port]\n", argv[0]); return 1; } int port = 23; if (argc == 3) port = atoi(argv[2]); //Create socket sock = socket(AF_INET , SOCK_STREAM , 0); if (sock == -1) { perror("Could not create socket. Error"); return 1; } server.sin_addr.s_addr = inet_addr(argv[1]); server.sin_family = AF_INET; server.sin_port = htons(port); //Connect to remote server if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) { perror("connect failed. Error"); return 1; } puts("Connected...\n"); // set terminal terminal_set(); atexit(terminal_reset); struct timeval ts; ts.tv_sec = 1; // 1 second ts.tv_usec = 0; while (1) { // select setup fd_set fds; FD_ZERO(&fds); if (sock != 0) FD_SET(sock, &fds); FD_SET(0, &fds); // wait for data int nready = select(sock + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts); if (nready < 0) { perror("select. Error"); return 1; } else if (nready == 0) { ts.tv_sec = 1; // 1 second ts.tv_usec = 0; } else if (sock != 0 && FD_ISSET(sock, &fds)) { // start by reading a single byte int rv; if ((rv = recv(sock , buf , 1 , 0)) < 0) return 1; else if (rv == 0) { printf("Connection closed by the remote end\n\r"); return 0; } if (buf[0] == CMD) { // read 2 more bytes len = recv(sock , buf + 1 , 2 , 0); if (len < 0) return 1; else if (len == 0) { printf("Connection closed by the remote end\n\r"); return 0; } negotiate(sock, buf, 3); } else { len = 1; buf[len] = '\0'; printf("%s", buf); fflush(0); } } else if (FD_ISSET(0, &fds)) { buf[0] = getc(stdin); //fgets(buf, 1, stdin); if (send(sock, buf, 1, 0) < 0) return 1; if (buf[0] == '\n') // with the terminal in raw mode we need to force a LF putchar('\r'); } } close(sock); return 0; }
You can download the source code for this telnet client here.
Related posts
Great start for a quick-and-dirty telnet client. Multiple bugs with the port though. Needs ^] handling too.
You are right, port hardcoded and bad test on argc – thanks!
How would be the server side coding for this program.
Also how to execute this program. I am new to socket programming, when I tried executing this program ,it throws an error of connection refused. Kindly help
You need to enable telnetd daemon before you run this client. If you are using Ubuntu Linux then follow these instructions.
http://ubuntuguide.net/install-and-enable-telnet-server-in-ubuntu-linux
In order to compile this program on Ubuntu Linux, simply do
sudo apt-get install build-essential
Then save this program as ‘telnet-client.c’
From the terminal, navigate to the folder
cd
gcc -g telnet-client.c -o telnet-client
Now run the program (It will ask for your Ubuntu Linux Login and password)
telnet-client 127.0.0.1 23
And you sould see something similar to this
./telnet-client 127.0.0.1 23
Connected…
Ubuntu 12.04.5 LTS
ubuntu login: virgo
Password:
Last login: Wed Oct 1 07:38:46 PDT 2014 from localhost on pts/4
Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.13.0-36-generic x86_64)
* Documentation: https://help.ubuntu.com/
New release ‘14.04.1 LTS’ available.
Run ‘do-release-upgrade’ to upgrade to it.
Your Hardware Enablement Stack (HWE) is supported until April 2017.
Says “network is unreachable” when I follow the above instructions even after installing telnetd
This worked. http://www.tenouk.com/Module40c.html