#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>

#include "libtelnet.h"

static int server_sock;
static int client_sock;

static struct libtelnet_t server_telnet;
static struct libtelnet_t client_telnet;

static const char *get_name(int sock) {
	if (sock == server_sock)
		return "\e[31mSERVER";
	else
		return "\e[34mCLIENT";
}

static const char *get_cmd(unsigned char cmd) {
	static char buffer[4];

	switch (cmd) {
	case 255: return "IAC";
	case 254: return "DONT";
	case 253: return "DO";
	case 252: return "WONT";
	case 251: return "WILL";
	case 250: return "SB";
	case 249: return "GA";
	case 248: return "EL";
	case 247: return "EC";
	case 246: return "AYT";
	case 245: return "AO";
	case 244: return "IP";
	case 243: return "BREAK";
	case 242: return "DM";
	case 241: return "NOP";
	case 240: return "SE";
	case 239: return "EOR";
	case 238: return "ABORT";
	case 237: return "SUSP";
	case 236: return "xEOF";
	default:
		snprintf(buffer, sizeof(buffer), "%d", (int)cmd);
		return buffer;
	}
}

static const char *get_opt(unsigned char opt) {
	switch (opt) {
	case 0: return "BINARY";
	case 1: return "ECHO";
	case 2: return "RCP";
	case 3: return "SGA";
	case 4: return "NAMS";
	case 5: return "STATUS";
	case 6: return "TM";
	case 7: return "RCTE";
	case 8: return "NAOL";
	case 9: return "NAOP";
	case 10: return "NAOCRD";
	case 11: return "NAOHTS";
	case 12: return "NAOHTD";
	case 13: return "NAOFFD";
	case 14: return "NAOVTS";
	case 15: return "NAOVTD";
	case 16: return "NAOLFD";
	case 17: return "XASCII";
	case 18: return "LOGOUT";
	case 19: return "BM";
	case 20: return "DET";
	case 21: return "SUPDUP";
	case 22: return "SUPDUPOUTPUT";
	case 23: return "SNDLOC";
	case 24: return "TTYPE";
	case 25: return "EOR";
	case 26: return "TUID";
	case 27: return "OUTMRK";
	case 28: return "TTYLOC";
	case 29: return "3270REGIME";
	case 30: return "X3PAD";
	case 31: return "NAWS";
	case 32: return "TSPEED";
	case 33: return "LFLOW";
	case 34: return "LINEMODE";
	case 35: return "XDISPLOC";
	case 36: return "ENVIRON";
	case 37: return "AUTHENTICATION";
	case 38: return "ENCRYPT";
	case 39: return "NEW-ENVIRON";
	case 70: return "MSSP";
	case 85: return "COMPRESS";
	case 86: return "COMPRESS2";
	case 93: return "ZMP";
	case 255: return "EXOPL";
	default: return "unknown";
	}
}

static struct libtelnet_t *other_telnet(struct libtelnet_t *telnet) {
	if (telnet == &server_telnet)
		return &client_telnet;
	else
		return &server_telnet;
}

static void* other_socket(int sock) {
	if (sock == server_sock)
		return (void*)&client_sock;
	else
		return (void*)&server_sock;
}

static void print_buffer(unsigned char *buffer, unsigned int size) {
	unsigned int i;
	for (i = 0; i != size; ++i) {
		if (buffer[i] == ' ' || (isprint(buffer[i]) && !isspace(buffer[i])))
			printf("%c", (char)buffer[i]);
		else if (buffer[i] == '\n')
			printf("<%02X>\n", (int)buffer[i]);
		else
			printf("<%02X>", (int)buffer[i]);
	}
}

void libtelnet_data_cb(struct libtelnet_t *telnet, unsigned char *buffer,
		unsigned int size, void *user_data) {
	int sock = *(int*)user_data;

	printf("%s DATA: ", get_name(sock));
	print_buffer(buffer, size);
	printf("\e[0m\n");

	libtelnet_send_data(other_telnet(telnet), buffer, size,
			other_socket(sock));
}

void libtelnet_send_cb(struct libtelnet_t *telnet, unsigned char *buffer,
		unsigned int size, void *user_data) {
	int sock = *(int*)user_data;

	/* DONT SPAM
	printf("%s SEND: ", get_name(sock));
	print_buffer(buffer, size);
	printf("\e[0m\n");
	*/

	/* send data */
	send(sock, buffer, size, 0);
}

void libtelnet_command_cb(struct libtelnet_t *telnet, unsigned char cmd,
		void *user_data) {
	int sock = *(int*)user_data;

	printf("%s IAC %s\e[0m\n", get_name(sock), get_cmd(cmd));

	libtelnet_send_command(other_telnet(telnet), cmd, other_socket(sock));
}

void libtelnet_negotiate_cb(struct libtelnet_t *telnet, unsigned char cmd,
		unsigned char opt, void *user_data) {
	int sock = *(int*)user_data;

	printf("%s IAC %s %d (%s)\e[0m\n", get_name(sock), get_cmd(cmd),
			(int)opt, get_opt(opt));

	libtelnet_send_negotiate(other_telnet(telnet), cmd, opt,
			other_socket(sock));
}

void libtelnet_subrequest_cb(struct libtelnet_t *telnet, unsigned char type,
		unsigned char *buffer, unsigned int size, void *user_data) {
	int sock = *(int*)user_data;

	printf("%s SUB %d (%s)", get_name(sock), (int)type, get_opt(type));
	if (size > 0) {
		printf(": ");
		print_buffer(buffer, size);
	}
	printf("\e[0m\n");

	libtelnet_send_subrequest(other_telnet(telnet), type, buffer, size,
			other_socket(sock));
}

void libtelnet_error_cb(struct libtelnet_t *telnet,
		enum libtelnet_error_t error, void *user_data) {
	int sock = *(int*)user_data;

	printf("%s ERROR: %d\e[0m\n", get_name(sock), (int)error);
}

int main(int argc, char **argv) {
	unsigned char buffer[512];
	int listen_sock;
	int rs;
	struct sockaddr_in addr;
	socklen_t addrlen;
	struct pollfd pfd[2];

	/* check usage */
	if (argc != 4) {
		fprintf(stderr, "Usage:\n ./telnet-proxy <remote ip> <remote port> <local port>\n");
		return 1;
	}
	
	/* create listening socket */
	if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		fprintf(stderr, "socket() failed: %s\n", strerror(errno));
		return 1;
	}

	/* re-use addr */
	rs = 1;
	setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &rs, sizeof(rs));

	/* bind */
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(strtol(argv[3], 0, 10));
	if (bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
		fprintf(stderr, "bind() failed: %s\n", strerror(errno));
		return 1;
	}

	/* listen */
	if (listen(listen_sock, 5) == -1) {
		fprintf(stderr, "listen() failed: %s\n", strerror(errno));
		return 1;
	}

	/* wait for client connection */
	if ((client_sock = accept(listen_sock, (struct sockaddr *)&addr, &addrlen)) == -1) {
		fprintf(stderr, "accept() failed: %s\n", strerror(errno));
		return 1;
	}
	
	/* create server socket */
	if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		fprintf(stderr, "socket() failed: %s\n", strerror(errno));
		return 1;
	}

	/* bind */
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	if (bind(server_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
		fprintf(stderr, "bind() failed: %s\n", strerror(errno));
		return 1;
	}

	/* connect */
	memset(&addr, 0, sizeof(addr));
	if (inet_pton(AF_INET, argv[1], &addr.sin_addr) != 1) {
		fprintf(stderr, "inet_pton() failed: %s\n", strerror(errno));
		return 1;
	}
	addr.sin_family = AF_INET;
	addr.sin_port = htons(strtol(argv[2], 0, 10));
	if (connect(server_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
		fprintf(stderr, "server() failed: %s\n", strerror(errno));
		return 1;
	}

	/* initialize telnet boxes */
	libtelnet_init(&server_telnet);
	libtelnet_init(&client_telnet);

	/* initialize poll descriptors */
	memset(pfd, 0, sizeof(pfd));
	pfd[0].fd = server_sock;
	pfd[0].events = POLLIN | POLLHUP;
	pfd[1].fd = client_sock;
	pfd[1].events = POLLIN | POLLHUP;

	/* loop while both connections are open */
	while (poll(pfd, 2, -1) != -1) {
		/* read from server */
		if (pfd[0].revents & POLLIN) {
			if ((rs = recv(pfd[0].fd, buffer, sizeof(buffer), 0)) > 0)
				libtelnet_push(&server_telnet, buffer, rs, (void*)&pfd[0].fd);
		}
		if (pfd[0].revents & POLLHUP)
			break;

		/* read from client */
		if (pfd[1].revents & POLLIN) {
			if ((rs = recv(pfd[1].fd, buffer, sizeof(buffer), 0)) > 0)
				libtelnet_push(&client_telnet, buffer, rs, (void*)&pfd[1].fd);
		}
		if (pfd[1].revents & POLLHUP)
			break;
	}

	/* clean up */
	libtelnet_free(&server_telnet);
	libtelnet_free(&client_telnet);
	close(server_sock);
	close(client_sock);
	close(listen_sock);

	return 0;
}
