diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2014-07-14 22:31:04 -0400 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2014-07-14 22:31:04 -0400 |
| commit | 3b104903087460158fd79c9cae27ada2d4dc103e (patch) | |
| tree | 0d928355a981d37e2e72186828deebdae537150b /server.c | |
| parent | f10cfb8bd77327b73da570730dee794d83b5c6ad (diff) | |
| download | wargames-server-3b104903087460158fd79c9cae27ada2d4dc103e.zip wargames-server-3b104903087460158fd79c9cae27ada2d4dc103e.tar.gz wargames-server-3b104903087460158fd79c9cae27ada2d4dc103e.tar.bz2 wargames-server-3b104903087460158fd79c9cae27ada2d4dc103e.tar.xz | |
Added some features to telnet server
Diffstat (limited to 'server.c')
| -rw-r--r-- | server.c | 117 |
1 files changed, 110 insertions, 7 deletions
@@ -19,6 +19,7 @@ */ #include "joshua.h" +#include "util.h" #include <errno.h> #include <netdb.h> #include <netinet/in.h> @@ -29,10 +30,11 @@ #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> - +#define DEFAULT_PORT 23 int server_socket; uint16_t port; int pipes[FD_SETSIZE][2]; +struct connection_data_t connection_data[FD_SETSIZE]; int make_server_socket(uint16_t port) { int sock; @@ -40,7 +42,7 @@ int make_server_socket(uint16_t port) sock=socket(AF_INET, SOCK_STREAM, 0); if(sock<0) { - printf("error creating socket.\n"); + printf("error opening socket.\n"); return -1; } name.sin_family=AF_INET; @@ -56,7 +58,7 @@ int make_server_socket(uint16_t port) } int process_data(int fd) { - char buf[1024]; + unsigned char buf[1024]; memset(buf, 0, sizeof(buf)); int ret=read(fd, buf, sizeof(buf)); char ctrl_c[]={0xff, 0xf4, 0xff, 0xfd, 0x06, 0x00}; @@ -78,7 +80,91 @@ int process_data(int fd) else { printf("Client sends: %s\n", buf); - write(pipes[fd][1], buf, strlen(buf)); + if(strlen(buf)>0) + { + if(buf[0]==0xff) + { + printf("String is command.\n"); + printf("Hex dump: "); + for(int i=0;buf[i];++i) + { + printf("%d ", buf[i]); + } + if(strlen(buf)<2) + { + printf("Bad command (length<3).\n"); + return 0; /* not a fatal error */ + } + unsigned char cmd=buf[1]; +#define WILL 251 +#define WONT 252 +#define DO 253 +#define DONT 254 +#define SB 250 +#define SE 240 +#define AYT 246 +#define NAWS 31 + unsigned char opt=(strlen(buf)==2)?0:buf[2]; + unsigned char nop[2]={0xff, 241}; + switch(cmd) + { + case AYT: + /* respond with IAC NOP */ + write(fd, nop, 2); + break; + case WILL: + case DO: + if(cmd==NAWS) + { + printf("Client offers NAWS\n"); + } + else if(cmd==1) + { + printf("Client offers echo.\n"); + } + break; + case WONT: + case DONT: + if(cmd==NAWS) + { + printf("Client denies NAWS.\n"); + } + else if(cmd==1) + { + printf("Client denies echo.\n"); + } + break; + default: + printf("Unknown command.\n"); + break; + } + if(cmd==SB) + { + if(opt==NAWS) + { + if(strlen(buf)>=9) + { + uint16_t width, height; + uint8_t width_hi, width_lo, height_hi, height_lo; + width_hi=buf[3]; + width_lo=buf[4]; + height_hi=buf[5]; + height_lo=buf[6]; + width=(width_hi<<8)|width_lo; + height=(height_hi<<8)|height_lo; + connection_data[fd].know_termsize=(width==0 || height==0)?0:1; /* if any dimension is zero, unknown */ + connection_data[fd].term_height=height; + connection_data[fd].term_width=width; + printf("Client window is %dx%d\n", width, height); + } + } + } + } + else + { + write(pipes[fd][1], buf, strlen(buf)); + } + } return 0; } } @@ -88,14 +174,29 @@ void serv_cleanup() fflush(stdout); shutdown(server_socket, SHUT_RDWR); } +void setup_new_connection(int fd) +{ + unsigned char will_naws[]={0xff, 251, 31}; + write(fd, will_naws, sizeof(will_naws)); + memset(&connection_data[fd], 0, sizeof(struct connection_data_t)); +} int main(int argc, char* argv[]) { if(argc!=2) { - printf("Usage: %s PORT\n", argv[0]); - return 2; + printf("Listening on default port: %d\n", DEFAULT_PORT); + port=DEFAULT_PORT; + } + else + { + int port2=atoi(argv[1]); + if(port2<0 || port2>65535) + { + printf("Port out of range.\n"); + return 2; + } + port=atoi(argv[1]); } - port=atoi(argv[1]); printf("Initializing server on port %u...\n", port); signal(SIGINT, &serv_cleanup); int sock=make_server_socket(port); @@ -144,6 +245,8 @@ int main(int argc, char* argv[]) pid_t pid=fork(); if(pid==0) /* child */ { + /* set up the connection */ + setup_new_connection(new); be_joshua(new); printf("Client exits\n"); shutdown(new, SHUT_RDWR); |