#include #include #include #include #include /* socket, sockaddr, ... */ #include /* gethostbyaddr */ #include #include /* perror */ #include #include #include "misc.h" #define F_STRING "__LIN_0.10" char* helium_get_actual_value(cfg *helium_cfg) { struct hostent *h; struct sockaddr_in cli_addr, srv_addr; int sockfd; int i, len, from_length; char sbuf[80], rbuf[80]; struct timeval tv; fd_set rfds; int selval; h = gethostbyname(helium_cfg->params.helium.hostname); if (!h) { perror("Cannot resolve hostname"); return NULL; } if (!h->h_addr_list[0]) { fprintf(stderr, "No addresses returned\n"); return NULL; } if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { perror("Cannot open socket"); return NULL; }; if (-1 == fcntl(sockfd, F_SETFL, O_NONBLOCK)) { perror("Canon setup socket\n"); return NULL; }; memset((char *) &cli_addr, 0, sizeof(cli_addr)); cli_addr.sin_family = AF_INET; cli_addr.sin_addr.s_addr = INADDR_ANY; cli_addr.sin_port = 0; /* nejake cislo portu bude prideleno */ if (bind(sockfd, (struct sockaddr *)&cli_addr, sizeof(cli_addr)) < 0) { perror("Bind error"); close(sockfd); return NULL; }; memset((char *) &srv_addr, 0, sizeof(srv_addr)); srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(helium_cfg->params.helium.serverport); /* ECHO service */ srv_addr.sin_addr = *(struct in_addr*)h->h_addr_list[0]; strcpy(sbuf, F_STRING); len = strlen(sbuf); if ((i = sendto(sockfd, sbuf, len, 0, (struct sockaddr*)&srv_addr, sizeof(srv_addr))) < 0) { perror("Cannot send packet"); close(sockfd); return NULL; }; FD_ZERO(&rfds); FD_SET(sockfd, &rfds); tv.tv_sec = 30; tv.tv_usec = 100; if (!(selval = select(sockfd + 1, &rfds, NULL, NULL, &tv))) { return NULL; }; from_length = 80; if ((i = recvfrom(sockfd, rbuf, sizeof(rbuf), 0, (struct sockaddr*)&srv_addr, &from_length)) < 0) { close(sockfd); return NULL; }; rbuf[i] = '\x0'; close(sockfd); return strdup(rbuf); };