/* * daytime1/daytime.c -- * * A simple TCP over IPv4/IPv6 daytime client. */ #include #include #include #if 1 #include "tiny/csapp.h" #else #if 0 #include #include #include #include #include #else #include #include #endif #endif #include #include static const char *progname = "Test Client 2"; #ifndef WSAAPI /* getaddrinfo constants */ #define AI_PASSIVE 1 #define AI_CANONNAME 2 #define AI_NUMERICHOST 4 struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; struct addrinfo *ai_next; }; #endif /* * Establish a connection to a remote TCP server. First get the list * of potential network layer addresses and transport layer port * numbers. Iterate through the returned address list until an attempt * to establish a TCP connection is successful (or no other * alternative exists). */ static int tcp_connect(char *host, char *port) { #ifndef WSAAPI struct hostent *hp; struct sockaddr_in serveraddr; #endif struct addrinfo hints, *ai_list, *ai; int fd = 0; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; #ifdef WSAAPI int n = getaddrinfo(host, port, &hints, &ai_list); if (n) { fprintf(stderr, "%s: getaddrinfo: %s\n", // progname, gai_strerror(n)); progname, strerror(n)); exit(EXIT_FAILURE); } #else /* Fill in the server's IP address and port */ if ((hp = gethostbyname(host)) == NULL) return -2; /* check h_errno for cause of error */ bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(atoi(port)); bcopy((char *)hp->h_addr, (char *)&serveraddr.sin_addr.s_addr, hp->h_length); hints.ai_addr = (struct sockaddr *)&serveraddr; hints.ai_addrlen = sizeof(serveraddr); hints.ai_family = AF_INET; hints.ai_protocol = 0; hints.ai_next = NULL; ai_list = &hints; #endif for (ai = ai_list; ai; ai = ai->ai_next) { fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (fd < 0) { continue; } if (connect(fd, ai->ai_addr, ai->ai_addrlen) == 0) { break; } close(fd); } #ifdef WSAAPI freeaddrinfo(ai_list); #endif if (ai == NULL) { fprintf(stderr, "%s: socket or connect: failed for %s port %s\n", progname, host, port); exit(EXIT_FAILURE); } return fd; } /* * Close a TCP connection. This function trivially calls close() on * POSIX systems, but might be more complicated on other systems. */ static int tcp_close(int fd) { return close(fd); } /* * Create a listening TCP endpoint. First get the list of potential * network layter addresses and transport layer port numbers. Iterate * through the returned address list until an attempt to create a * listening TCP endpoint is successful (or no other alternative * exists). */ static int tcp_listen(char *port) { #ifndef WSAAPI struct sockaddr_in serveraddr; #endif struct addrinfo hints, *ai_list, *ai; int fd = 0, on = 1; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; #ifdef WSAAPI int n = getaddrinfo(NULL, port, &hints, &ai_list); if (n) { fprintf(stderr, "%s: getaddrinfo failed: %s\n", // progname, gai_strerror(n)); progname, strerror(n)); return -1; } #else bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); serveraddr.sin_port = htons(atoi(port)); hints.ai_addr = (struct sockaddr *)&serveraddr; hints.ai_addrlen = sizeof(serveraddr); hints.ai_family = AF_INET; hints.ai_protocol = 0; hints.ai_next = NULL; ai_list = &hints; #endif for (ai = ai_list; ai; ai = ai->ai_next) { fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (fd < 0) { continue; } setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (bind(fd, ai->ai_addr, ai->ai_addrlen) == 0) { break; } close(fd); } #ifdef WSAAPI freeaddrinfo(ai_list); #endif if (ai == NULL) { fprintf(stderr, "%s: bind failed for port %s\n", progname, port); return -1; } if (listen(fd, 42) < 0) { fprintf(stderr, "%s: listen failed: %s\n", progname, strerror(errno)); close(fd); return -1; } return fd; } /* * Accept a new TCP connection and write a message about who was * accepted to the system log. */ static int tcp_accept(int listen) { struct sockaddr_in ss; socklen_t ss_len = sizeof(ss); int fd; fd = accept(listen, (struct sockaddr *) &ss, &ss_len); if (fd == -1) { syslog(LOG_ERR, "accept failed: %s", strerror(errno)); return -1; } #ifdef WSAAPI char host[NI_MAXHOST]; char serv[NI_MAXSERV]; int n = getnameinfo((struct sockaddr *) &ss, ss_len, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST); if (n) { // syslog(LOG_ERR, "getnameinfo failed: %s", gai_strerror(n)); syslog(LOG_ERR, "getnameinfo failed: %s", strerror(n)); } else { syslog(LOG_DEBUG, "connection from %s:%s", host, serv); } #else { struct hostent *hp; char *haddrp; /* determine the domain name and IP address of the client */ hp = Gethostbyaddr((const char *)&ss.sin_addr.s_addr, sizeof(ss.sin_addr.s_addr), AF_INET); haddrp = inet_ntoa(ss.sin_addr); printf("connection from %s (%s)\n", hp->h_name, haddrp); //syslog(LOG_DEBUG, "connection from %s(%s)", host, serv); syslog(LOG_DEBUG, "connection from %s(%s)", hp->h_name, haddrp); } #endif return fd; } int main(int argc, char **argv) { int fdr, fdc,fdl,con; char *message,msg[128], *p; ssize_t n,l; size_t nn; //Set up a socket to init a robot to the server if (argc ==1) // fdr=tcp_connect("146.50.1.149","3000"); // pc-unreal fdr=tcp_connect("127.0.0.1","3000"); // localhost else fdr=tcp_connect(argv[1],"3000"); message="INIT {ClassName USARBot.P2AT} {Name robot2} {Location 3.41,9.96,-0.446}\r"; // Position Robot 2 in DM-Mapping printf("%s\n",message); nn = write(fdr, message, strlen(message)); //Set up a socket to connect to the server if (argc ==1) // fdc=tcp_connect("146.50.1.149","5874"); // pc-unreal fdc=tcp_connect("127.0.0.1","5874"); // localhost else fdc=tcp_connect(argv[1],argv[2]); #ifdef WSAAPI char host[NI_MAXHOST]; char serv[NI_MAXSERV]; struct sockaddr_storage peer; socklen_t peerlen = sizeof(peer); /* Get the socket address of the remote end and convert it * into a human readable string (numeric format). */ int n = getpeername(fdc, (struct sockaddr *) &peer, &peerlen); if (n) { fprintf(stderr, "%s: getpeername: %s\n", progname, strerror(errno)); return errno; } n = getnameinfo((struct sockaddr *) &peer, peerlen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV); if (n) { fprintf(stderr, "%s: getnameinfo: %s\n", // progname, gai_strerror(n)); progname, strerror(n)); return n; } #endif //Register with the Server message="register robot2 146.50.1.56;"; printf("%s\n",message); nn = write(fdc, message, strlen(message)); if (nn != strlen(message)) { fprintf(stderr, "Write Failed\n"); return -1; } printf("Message sent\n"); //Wait for OK response while ((n = read(fdc, msg, sizeof(msg) - 1)) > 0) { msg[n] = '\0'; p = strstr(msg, ";"); if (p) *p = 0; //Print response on stdout printf("%s\n", msg); if(msg[0]=='O' && msg[1]=='K'){ //Open a connection (connect) message="open robot2 7798 robot1 7795;"; printf("%s\n",message); nn = write(fdc, message, strlen(message)); if (nn != strlen(message)) { fprintf(stderr, "Write Failed\n"); return -1; } printf("Message sent\n"); //Open connection to Listen fdl = tcp_listen("7798"); //Wait for OK response while ((l = read(fdc, msg, sizeof(msg) - 1)) > 0) { msg[l] = '\0'; p = strstr(msg, ";"); if (p) *p = 0; //Print response printf("%s\n", msg); if(msg[0]=='O' && msg[1]=='K'){ //Close socket to server tcp_close(fdc); //Accept the connection con=tcp_accept(fdl); // program hangs here //Send a message message="Victim Typcho found;"; sprintf(msg, "SEND %d %s\n", strlen(message),message); nn = write(con, msg, strlen(msg)); if (nn != strlen(msg)) { fprintf(stderr, "Write Failed\n"); return -1; } printf("Message sent\n"); sleep(5); // otherwise connection is already gone before message is delivered. //Close the connection message="CLOSE;"; // TBC here a fork, thread or fd_select has to be implemented to allow handling of multiple clients printf("%s\n",message); nn = write(con, message, strlen(message)); if (nn != strlen(message)) { fprintf(stderr, "Write Failed\n"); return -1; } printf("Message sent\n"); sleep(5); // otherwise connection is already gone before message is delivered //Close the open connection tcp_close(fdl); break; } printf("waiting 1\n"); } printf("waiting 2\n"); } printf("waiting 3\n"); break; // waiting on what, connection is already closed at the server to allow new connection } return EXIT_SUCCESS; }