/* compile: gcc -Wall -o testserver testserver.c ./testserver --if --port */ #include #include #include #include #include #include #include #include #include #include #include #include #include //#define LOCAL_IP "130.235.185.193" //#define SRU_IP "130.235.185.193" #define TCP_LISTENQ 10 #define NETW_INTERFACE "eth0" #define FILE_BUF_SIZE 10000 #define TCP_SERVER 0 #define TCP_MAX_SERVERS 0 #define TCP_MAX_CONNECTS 4 typedef struct { struct sockaddr_in si_controlme; struct sockaddr_in si_broadcast; int port; char interface[64]; // interface char localip[128]; // local ip number to use char broadcastip[128]; // broadcast address } NETW; typedef struct { int socket; int client; int senddata; char from[512]; unsigned char buf[FILE_BUF_SIZE]; } SUBCONNECT; typedef struct { int signal_action; int nbpoll; int timeout; int clientSocket; int server; int lastfrom; struct pollfd fd[TCP_MAX_CONNECTS]; SUBCONNECT sub[TCP_MAX_CONNECTS]; } CONNECT; int findip(char *interface, char *ipaddress, char *bcaddress); int startTcpServer(CONNECT *conns,int serverport); int waitForConnection(CONNECT *conns); int sendstatus(int sockfd,char *command); NETW netw; CONNECT conns; int signal_stop = 0; int sendstatus(int sockfd,char *command) { send(sockfd, command, strlen(command), 0); // sendto(sockfd, recvBuff, strlen, 0, (struct sockaddr *) &serv_addr, slen)==-1) return 0; } /* Routine that returns the (last) ipnumber and broadcast number for the given interface */ int findip(char *interface, char *ipaddress, char *bcaddress) { struct sockaddr_in *ipaddr; struct ifaddrs *ifaddr, *ifa; if (getifaddrs(&ifaddr) == -1) { perror("ONE"); return errno; } ifa = ifaddr; while(ifa) { if(ifa->ifa_addr && (ifa->ifa_addr->sa_family == AF_INET)) { if(!strcmp(ifa->ifa_name,interface)) { ipaddr = (struct sockaddr_in *)ifa->ifa_addr; strcpy(ipaddress,inet_ntoa(ipaddr->sin_addr)); ipaddr = (struct sockaddr_in *)ifa->ifa_broadaddr; strcpy(bcaddress,inet_ntoa(ipaddr->sin_addr)); } } ifa = ifa->ifa_next; } freeifaddrs(ifaddr); return 0; } int startTcpServer(CONNECT *conns,int serverport) { int listenfd; int j; struct sockaddr_in servaddr; for (j = 0; j < TCP_MAX_CONNECTS; j++) { conns->fd[j].fd = -1; } printf("%s: starting server on port %d\n",__FUNCTION__,serverport); if ( (listenfd = socket(AF_INET, SOCK_STREAM,0)) >= 0) { bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; // inet_pton(AF_INET,serverip,&servaddr.sin_addr.s_addr); servaddr.sin_port = htons(serverport); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { printf("%s *ERROR BIND* %s\n",__FUNCTION__,strerror(errno)); return -1; } if (listen(listenfd, TCP_LISTENQ) < 0) { printf("%s *ERROR LISTEN* %s\n",__FUNCTION__,strerror(errno)); return -2; } } else { return -3; } conns->fd[TCP_SERVER].fd = listenfd; conns->fd[TCP_SERVER].events = POLLIN; conns->sub[TCP_SERVER].client = 0; conns->nbpoll++; conns->timeout = -1; return listenfd; } int waitForConnection(CONNECT *conns) { int j, n,istat, connfd, clientlen; int conaccept = 0; char from[512]; struct sockaddr_in clientaddr; int timeout = conns->timeout; clientlen = sizeof(clientaddr); istat = poll(conns->fd,TCP_MAX_CONNECTS,timeout); // printf("ISTAT=%X nbpoll %d\n",istat,conns->nbpoll); // fflush(stdout); if (istat == 0) return -3; else if (conns->fd[0].revents & POLLIN) { printf("CONNS 0\n"); clientlen = sizeof(clientaddr); connfd = accept(conns->fd[TCP_SERVER].fd, (struct sockaddr *) &clientaddr, (socklen_t *)&clientlen); if (conns->nbpoll >= TCP_MAX_CONNECTS) { printf("%s max clients %d\n",__FUNCTION__,conns->nbpoll); close(connfd); } else { // Accept new connection if space available conaccept = 0; for (j = TCP_MAX_SERVERS; j < TCP_MAX_CONNECTS; j++) { if (conns->fd[j].fd == -1) { if (inet_ntop(AF_INET, &clientaddr.sin_addr,from,sizeof(from))) { conaccept = 1; conns->fd[j].fd = connfd; conns->fd[j].events = POLLIN; conns->nbpoll++; strncpy(conns->sub[j].from,from,sizeof(conns->sub[j].from)); conns->lastfrom = j; printf("%s: connect as %d nbpoll %d from %s port %d\n",__FUNCTION__,j,conns->nbpoll,from,ntohs(clientaddr.sin_port)); } else { printf("%s: erratic inet_ntop connect from %s\n",__FUNCTION__,from); close(connfd); } break; // return -2; } } if (conaccept == 0) { close(connfd); } } } else if (conns->nbpoll > 1) { for (j = TCP_MAX_SERVERS; j <= TCP_MAX_CONNECTS; j++) { if (conns->fd[j].revents & POLLHUP) { conns->nbpoll--; if ( close(conns->fd[j].fd) < 0 ) { printf("%s: Closeerror server\n",__FUNCTION__); } conns->fd[j].fd = -1; conns->sub[j].client = -1; printf("%s: HANGUP %d %d!!\n",__FUNCTION__,j,conns->nbpoll); } else if (conns->fd[j].revents & POLLIN) { if ((n = recvfrom(conns->fd[j].fd,conns->sub[j].buf,FILE_BUF_SIZE,0,(struct sockaddr *) &clientaddr,(socklen_t *)&clientlen )) > 0) { conns->lastfrom = j; conns->sub[j].buf[n] = '\0'; conns->sub[j].client = n; } else if ( n <= 0 ) { if ( close(conns->fd[j].fd) < 0 ) { printf("%s: Closeerror server\n",__FUNCTION__); } conns->fd[j].fd = -1; conns->sub[j].client = -1; conns->nbpoll--; printf("# %s: DISCONNECTED %d %d\n",__FUNCTION__,j,conns->nbpoll); conns->sub[j].senddata = 0; // we can not send more data to it return -1; } } } } return 0; } void signal_handler(int signum) { switch(signum) { case SIGQUIT: case SIGTERM: case SIGINT: puts("\nSIGNAL CAUGHT\n"); signal_stop = 1; if (conns.fd[2].fd > 0) close(conns.fd[2].fd); if (conns.fd[1].fd > 0) close(conns.fd[1].fd); if (conns.fd[0].fd > 0) close(conns.fd[0].fd); exit(1); } } int decodeParameters(int argc, char **argv) { int c; int option_index = 0; char *short_options = "i:p:"; const struct option long_options[]= { {"if",1,0,'i'}, {"port",1,0,'p'}, {0, 0, 0, 0} }; strncpy(netw.interface,NETW_INTERFACE,sizeof(netw.interface)); if (argc > 1) { while ((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != EOF) { switch (c) { case 'h': puts("Options"); puts("--if "); puts("--port "); return 1; break; case 'i': strncpy(netw.interface,optarg,sizeof(netw.interface)); break; case 'p': netw.port = atoi(optarg); break; default: printf("Unkown paramater\n"); return 1; } } } return 0; } int main(int argc, char **argv) { char msgbuf[64]; int iret; int listenfd; int lastfrom; int events = 0; int cont; int chipnumber; signal(SIGINT,signal_handler); signal(SIGQUIT,signal_handler); signal(SIGTERM,signal_handler); if (decodeParameters(argc,argv)) return 0; iret = findip(netw.interface,netw.localip,netw.broadcastip); if (iret != 0) { printf("exit after findip, error %s\n",strerror(iret)); return(0); } printf("\t Interface: <%s>\n",netw.interface); printf("\t Address : <%s>\n",netw.localip); printf("\t broadcast : <%s>\n",netw.broadcastip); listenfd = startTcpServer(&conns,2001); if (listenfd <= 0) return(0); cont = 1; while(cont) { iret = waitForConnection(&conns); lastfrom = conns.lastfrom; if (iret == -1) { // cont = 0; } else if (conns.sub[lastfrom].client > 0) { conns.sub[lastfrom].client = 0; if (conns.sub[lastfrom].buf[0] == 'T') { sscanf((char *)conns.sub[lastfrom].buf,"T%dT",&chipnumber); events++; sprintf(msgbuf,"./script.sh %d",chipnumber); iret = system(msgbuf); // Did not execute properly if (WEXITSTATUS(iret) == 127) sprintf(msgbuf,"R%d",8); // else get exit value of script as status of test else sprintf(msgbuf,"R%d",WEXITSTATUS(iret)); sendstatus(conns.fd[lastfrom].fd,msgbuf); } } if (signal_stop) cont = 0; } if (conns.fd[1].fd != -1) close(conns.fd[1].fd); close(listenfd); puts("\nEXIT"); return 0; }