-/* upd-server.c
- *
- * Copyright (c) 2000 Sean Walton and Macmillan Publishers. Use may be in
- * whole or in part in accordance to the General Public License (GPL).
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*****************************************************************************/
-/*** upd-server.c ***/
-/*** ***/
-/*** Create a datagram server that waits for client messages (which it ***/
-/*** echoes back). ***/
-/*****************************************************************************/
-
-#include <stdio.h>
#include <stdlib.h>
-#include <errno.h>
+#include <stdio.h>
+#include <signal.h>
#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <resolv.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/time.h>
+#include <errno.h>
#include <string.h>
+#include <stdint.h>
+#include <math.h>
+#include <trberror.h>
#include <sys/socket.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
#include <netdb.h>
#include <sys/select.h>
-#define DEFAULT_PORT 25000
-
+#include <arpa/inet.h>
+#include <sys/timeb.h>
-#if 0
-int main(int count, char *strings[])
-{
- int sd;
- int port = DEFAULT_PORT;
- struct sockaddr_in addr;
- uint16_t buffer[32768];
-
- if (count != 2)
- printf("usage: %s <port>\n...Using default port (%d).\n", strings[0],
- port);
- else
- port = atoi(strings[1]);
-
- sd = socket(PF_INET, SOCK_DGRAM, 0);
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = INADDR_ANY;
- if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
- perror("bind");
- while (1) {
- int bytes;
- socklen_t addr_len = sizeof(addr);
- int i;
-
- bytes =
- recvfrom(sd, (void*)buffer, sizeof(buffer), 0, (struct sockaddr *)&addr,
- &addr_len);
- printf("msg from %s:%d (%d bytes)\n", inet_ntoa(addr.sin_addr),
- ntohs(addr.sin_port), bytes);
- for (i = 0; i < bytes / 2; i++) {
- fprintf(stderr, "%d 0x%04x\n", i, buffer[i]);
- }
- sleep(7);
- sendto(sd, buffer, bytes, 0, (struct sockaddr *)&addr, sizeof(addr));
- fprintf(stderr, "sendto done\n");
- }
- close(sd);
-}
-#else
-
-static uint16_t udpBuffer[32768]; /* One UDP Package */
-static uint16_t dataBuffer[4096 * 1024];
+static uint16_t udpBufferS[1 + 32768]; /* One UDP Package + Header */
+static uint16_t* udpBuffer = udpBufferS + 1;
+static uint16_t dataBufferR[1 + 4096 * 1024]; /* UDP Receive buffer + Header */
+static uint16_t* dataBuffer = dataBufferR + 1;
static unsigned int dataBufferSize = 0; /* Size of dataBuffer in 16Bit words */
+static uint8_t udp_command_index = 0;
static int trb3_sockfd = -1;
-static struct sockaddr_in trb3_addr;
+static struct addrinfo* trb3_addrinfo = NULL;
static const struct timespec tv = {
.tv_sec = 3, /* UDP timeout for receive call */
.tv_nsec = 0
};
-static uint16_t trb3_port = 25000;
-uint16_t sender_address = 0x4455;
+static const char TRB3_UDP_PORT_OLD[] = "25000";
+static const char TRB3_UDP_PORT_NEW[] = "26000";
+static char trb3_server[NI_MAXHOST] = "trb3";
+static uint16_t sender_address = 0x5555;
+static uint8_t trb3_udp_version = 0;
+
+int trb_debug = 5;
+
+int init_ports()
+{
+ const struct addrinfo hints = {
+ .ai_family = AF_INET,
+ .ai_socktype = SOCK_DGRAM,
+ .ai_protocol = IPPROTO_UDP,
+ .ai_flags = AI_ADDRCONFIG | AI_CANONNAME | AI_NUMERICSERV,
+ .ai_addrlen = 0,
+ .ai_addr = NULL,
+ .ai_canonname = NULL,
+ .ai_next = NULL
+ };
+ const char* trb3_port = NULL;
+ char* tmp = NULL;
+ int status = -1;
+
+
+ trb_errno = TRB_NONE;
+
+ /* cleanup in case of repeated call */
+ if (trb3_addrinfo != NULL) {
+ trb3_addrinfo = NULL;
+ freeaddrinfo(trb3_addrinfo);
+ }
+ if (trb3_sockfd) {
+ trb3_sockfd = -1;
+ close(trb3_sockfd);
+ }
+
+ if (trb_debug > 0) {
+ fprintf(stderr, "init_ports: called\n");
+ }
+
+ /* Get TRB3 IP-Address */
+ tmp = getenv("TRB3_SERVER");
+ if (tmp != NULL) {
+ char* separator = NULL;
+ if ((separator = rindex(tmp, ':')) != NULL) {
+ *separator = '\0';
+ trb3_port = separator + 1;
+ } else {
+ trb3_port = TRB3_UDP_PORT_NEW;
+ }
+ strncpy(trb3_server, tmp, NI_MAXHOST);
+ } else {
+ /* Choose default name and port */
+ trb3_port = TRB3_UDP_PORT_OLD;
+ snprintf(trb3_server, NI_MAXHOST, "trb3");
+ }
+
+ /* New Trbnet UDP Version settings */
+ if (strcmp(trb3_port, TRB3_UDP_PORT_OLD) != 0) {
+ struct timeb t;
+ ftime(&t);
+ srand(t.millitm); /* always new seed for command index start */
+ udp_command_index = (uint8_t)rand();
+ udpBuffer = udpBufferS + 1;
+ dataBuffer = dataBufferR + 1;
+ trb3_udp_version = 2;
+ } else {
+ udpBuffer = udpBufferS;
+ dataBuffer = dataBufferR;
+ trb3_udp_version = 1;
+ }
+
+ if (trb_debug > 2) {
+ fprintf(stderr, "init_ports: trb3_server: %s port: %s UDP-Version: %d\n",
+ trb3_server, trb3_port, trb3_udp_version);
+ }
+
+ /* Get TRB3 Server FQDN */
+ status = getaddrinfo(trb3_server,
+ trb3_port,
+ &hints,
+ &trb3_addrinfo);
+ if (status != 0) {
+ if (trb_debug > 2) {
+ if (status == EAI_SYSTEM) {
+ fprintf(stderr, "init_ports: getaddrinfo (EAI_SYSTEM) : %s\n",
+ strerror(status));
+ } else {
+ fprintf(stderr, "init_ports: getaddrinfo (lookup): %s\n",
+ gai_strerror(status));
+ }
+ }
+ trb_errno = TRB_TRB3_SOCKET_ERROR;
+ return -1;
+ }
+
+ if ((trb3_addrinfo == NULL) || (trb3_addrinfo->ai_addr == NULL)) {
+ trb_errno = TRB_TRB3_SOCKET_ERROR;
+ return -1;
+ }
+
+ /* Create Socket */
+ trb3_sockfd = socket(trb3_addrinfo->ai_family,
+ trb3_addrinfo->ai_socktype | SOCK_CLOEXEC,
+ trb3_addrinfo->ai_protocol);
+
+ if (trb3_sockfd == -1) {
+ if (trb_debug > 2) {
+ fprintf(stderr, "init_ports: socket(...) failed: %s\n",
+ strerror(errno));
+ }
+ freeaddrinfo(trb3_addrinfo);
+ trb3_addrinfo = NULL;
+ trb_errno = TRB_TRB3_SOCKET_ERROR;
+ return -1;
+ }
+
+
+ return 0;
+}
static int getUDPPackage()
{
int status;
int i;
+ dataBufferR[0] = '\0';
dataBufferSize = 0;
-
+
/* GetData */
- fprintf(stderr, "Wait UDP Data\n");
-
+ if (trb_debug > 2) {
+ fprintf(stderr, "Wait UDP Data\n");
+ }
+
/* Wait for data ready and Set Socket Timeout */
FD_ZERO(&fds);
FD_SET(trb3_sockfd, &fds);
status = pselect(trb3_sockfd + 1, &fds, NULL, NULL, &tv, NULL);
if (status == -1) {
- fprintf(stderr, "TRB_TRB3_SOCKET_ERROR\n");
+ trb_errno = TRB_TRB3_SOCKET_ERROR;
return -1;
}
if (FD_ISSET(trb3_sockfd, &fds) == 0) {
- fprintf(stderr, "TRB_TRB3_SOCKET_TIMEOUT\n");
+ trb_errno = TRB_TRB3_SOCKET_TIMEOUT;
return -1;
}
/* Read Data */
status = recvfrom(trb3_sockfd,
- (void*)dataBuffer,
+ (void*)dataBufferR,
65536,
MSG_DONTWAIT,
(struct sockaddr*)&in_addr,
&in_addr_len);
if (status == -1) {
- fprintf(stderr, "TRB_TRB3_SOCKET_ERROR\n");
+ trb_errno = TRB_TRB3_SOCKET_ERROR;
return -1;
}
dataBufferSize = status / 2;
- fprintf(stderr, "udp received: %d\n", status);
+ if (trb_debug > 2) {
+ fprintf(stderr, "udp received: %d\n", status);
+ }
/* Adjust endianess ... */
for (i = 0; i < status / 2; i++) {
- dataBuffer[i] = ntohs(dataBuffer[i]);
- fprintf(stderr, "%d 0x%04x\n", i, dataBuffer[i]);
+ dataBufferR[i] = ntohs(dataBufferR[i]);
+ if (trb_debug > 2) {
+ fprintf(stderr, "%d 0x%04x\n", i, dataBufferR[i]);
+ }
}
+ /* Check returned udp_command_index */
+ if (trb3_udp_version == 2) {
+ uint8_t command_index_type = (uint8_t)(dataBufferR[0] >> 8);
+ uint8_t command_index_ret = (uint8_t)(dataBufferR[0] & 0x00ff);
+ if (command_index_type != 2) {
+ if (trb_debug > 1) {
+ fprintf(stderr, "getUDPPackage: invalid command_index_type: %d\n",
+ command_index_type);
+ }
+ trb_errno = TRB_TRB3_INVALID_UDP_HEADER;
+ return -1;
+ }
+
+ if (command_index_ret!= udp_command_index) {
+ if (trb_debug > 1) {
+ fprintf(stderr,
+ "getUDPPackage: invalid : udp_command_index: %d != %d\n",
+ command_index_ret, udp_command_index);
+ }
+ trb_errno = TRB_TRB3_INVALID_UDP_HEADER;
+ return -1;
+ }
+ }
+
return status;
}
-
-int main(int argc, char** argv)
+static int sendTrbPackage(size_t size, int recv)
{
unsigned int timeoutCtr = 0;
- int status = -1;
- char* trb3_name = NULL;
- struct hostent* host = NULL;
+ int status;
+ int i;
- /* Get TRB3 IP-Address */
- trb3_name = getenv("TRB3_SERVER");
- if (trb3_name == NULL) {
- trb3_name = "pexor";
+ if (trb3_udp_version == 2) {
+ /* Add udp_command_index */
+ udpBufferS[0] = 0x0100 | udp_command_index++;
+ size++;
}
-
- if ((host = gethostbyname(trb3_name)) == NULL) {
- abort();
+
+ /* Adjust endianess ... */
+ for (i = 0; i < size; i++) {
+ if (trb_debug > 2) {
+ if (i == 0) {
+ fprintf(stderr, "udp sent:\n");
+ }
+ fprintf(stderr, "%d 0x%04x\n", i, udpBufferS[i]);
+ }
+ udpBufferS[i] = htons(udpBufferS[i]);
}
- /* Create Socket */
- trb3_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
- if (trb3_sockfd == -1) {
- abort();
- }
-
- /* Create Target Address */
- trb3_addr.sin_family = AF_INET;
- trb3_addr.sin_port = htons(trb3_port);
- trb3_addr.sin_addr = *((struct in_addr*)host->h_addr);
- memset(&(trb3_addr.sin_zero), 0, 8);
+ while (timeoutCtr < 1) {
+ if (trb_debug > 2) {
+ fprintf(stderr, "Send UDP request attempt #%d\n", timeoutCtr);
+ }
+
+ /* Send request */
+ status = sendto(trb3_sockfd,
+ (void*)udpBufferS,
+ size * 2,
+ MSG_CONFIRM,
+ trb3_addrinfo->ai_addr,
+ trb3_addrinfo->ai_addrlen
+ );
+ if (status == -1) {
+ if (trb_debug > 1) {
+ fprintf(stderr, "sendto failed: %s\n", strerror(errno));
+ }
+ trb_errno = TRB_TRB3_SOCKET_ERROR;
+
+ return -1;
+ }
+
+ if (recv == 0) return 0;
+ /* GetData */
+ status = getUDPPackage();
+ if (status > 0) break; /* Success */
+ if (trb_errno == TRB_TRB3_SOCKET_ERROR) return -1; /* UDP Error */
- while (timeoutCtr < 3) {
- /* GetData */
- fprintf(stderr, "\n\nSend UDP request attempt #%d\n", timeoutCtr);
- status = getUDPPackage();
- if (status > 0) break; /* Success */
-
/* UDP Timeout, resend request */
timeoutCtr++;
}
+
+ return status;
+}
- /* Socket Port?? */
+
+int main(int count, char *strings[])
+{
+ init_ports();
+
+ //getUDPPackage();
+
+
+ udpBufferS[0] = 0x0031;
+ udpBufferS[1] = 0x5555;
+ udpBufferS[2] = 0xf3c0;
+ udpBufferS[3] = 0x0000;
+ udpBufferS[4] = 0x0008;
+ udpBufferS[5] = 0x0030;
+ udpBufferS[6] = 0x0000;
+ udpBufferS[7] = 0x0000;
+ udpBufferS[8] = 0x0000;
+ udpBufferS[9] = 0x0000;
+ udpBufferS[10] = 0x0033;
+ udpBufferS[11] = 0x0000;
+ udpBufferS[12] = 0x0000;
+ udpBufferS[13] = 0x0000;
+ udpBufferS[14] = 0x0008;
+
+ fprintf(stderr, "-0---------------------------------------------\n");
+ sendTrbPackage(15, 0);
+ sleep(1);
+
+ udpBufferS[0] = 0x0031;
+ udpBufferS[1] = 0x5555;
+ udpBufferS[2] = 0xf306;
+ udpBufferS[3] = 0x0000;
+ udpBufferS[4] = 0x0008;
+ udpBufferS[5] = 0x0030;
+ udpBufferS[6] = 0x0000;
+ udpBufferS[7] = 0x0000;
+ udpBufferS[8] = 0x0000;
+ udpBufferS[9] = 0x0000;
+ udpBufferS[10] = 0x0033;
+ udpBufferS[11] = 0x0000;
+ udpBufferS[12] = 0x0000;
+ udpBufferS[13] = 0x0000;
+ udpBufferS[14] = 0x0008;
+
+ fprintf(stderr, "-1---------------------------------------------\n");
+ sendTrbPackage(15, 1);
+ fprintf(stderr, "-R2---------------------------------------------\n");
+ getUDPPackage();
+
{
- struct sockaddr in_addr;
- status = getsockname(trb3_sockfd,
- struct sockaddr *addr,
- socklen_t *addrlen
- );
+ int recv_port = -1;
+ struct sockaddr_in tmp;
+ socklen_t socksize = sizeof(struct sockaddr_in);
+ recv_port = getsockname(trb3_sockfd,
+ (struct sockaddr*)&tmp,
+ &socksize
+ );
+ if (recv_port != 0) {
+ perror("getsockname");
+ return -1;
+ }
+ fprintf(stderr, "recv_port: 0x%08x\n", tmp.sin_family);
+ fprintf(stderr, "recv_port: 0x%08x\n", tmp.sin_port);
+ fprintf(stderr, "recv_port: 0x%08x\n", tmp.sin_addr.s_addr);
+
}
+ exit(EXIT_SUCCESS);
- status = getUDPPackage();
- fprintf(stderr, "getUDPPackage() Status %d\n", status);
- return 0;
}
-
-
-#endif