diff utils/smpp-test1.c @ 218:211a043a385f

smpp-test1 program written, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 01 Aug 2023 22:38:04 -0800
parents
children 9ba474e918c0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/smpp-test1.c	Tue Aug 01 22:38:04 2023 -0800
@@ -0,0 +1,153 @@
+/*
+ * This program connects to an SMPP server in the role of a client,
+ * sends a bind_transceiver request, and then dumps everything
+ * that comes back.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+
+static const u_char bind_req[] = {
+	0x00, 0x00, 0x00, 0x17,		/* command_length */
+	0x00, 0x00, 0x00, 0x09,		/* command_id: bind_transceiver */
+	0x00, 0x00, 0x00, 0x00,		/* command_status */
+	0x00, 0x00, 0x00, 0x00,		/* sequence_number */
+	0, 0, 0,			/* empty strings */
+	0x34,				/* interface_version */
+	0, 0, 0				/* empty address params */
+};
+
+static int tcpsock;
+static struct sockaddr_in server_sin;
+static u_char rx_hdr[16];
+static unsigned rx_pkt_len;
+
+static void
+init_stage()
+{
+	int rc;
+
+	rc = connect(tcpsock, (struct sockaddr *) &server_sin,
+		     sizeof(struct sockaddr_in));
+	if (rc < 0) {
+		perror("connect");
+		exit(1);
+	}
+	rc = write(tcpsock, bind_req, sizeof bind_req);
+	if (rc != sizeof bind_req) {
+		perror("write");
+		exit(1);
+	}
+}
+
+static void
+rx_bytes(buf, need_len)
+	u_char *buf;
+	unsigned need_len;
+{
+	int cc;
+	unsigned remain;
+
+	for (remain = need_len; remain; remain -= cc) {
+		cc = read(tcpsock, buf, remain);
+		if (cc <= 0) {
+			perror("read");
+			exit(1);
+		}
+	}
+}
+
+static void
+print_hdr()
+{
+	int i, j, pos;
+
+	fputs("Got header:", stdout);
+	pos = 0;
+	for (i = 0; i < 4; i++) {
+		putchar(' ');
+		for (j = 0; j < 4; j++)
+			printf("%02X", rx_hdr[pos++]);
+	}
+	putchar('\n');
+}
+
+static void
+preen_rx_len()
+{
+	rx_pkt_len = (rx_hdr[0] << 24) | (rx_hdr[1] << 16) | (rx_hdr[2] << 8) |
+			rx_hdr[3];
+	printf("Rx packet length: %u bytes\n", rx_pkt_len);
+	if (rx_pkt_len < 16) {
+		printf("Error: packet length is too short\n");
+		exit(1);
+	}
+}
+
+static void
+read_and_dump_body()
+{
+	u_char buf[16];
+	unsigned offset, chunk;
+	int i, c;
+
+	for (offset = 16; offset < rx_pkt_len; offset += chunk) {
+		chunk = rx_pkt_len - offset;
+		if (chunk > 16)
+			chunk = 16;
+		rx_bytes(buf, chunk);
+		printf("%08X:  ", offset);
+		for (i = 0; i < 16; i++) {
+			if (i < chunk)
+				printf("%02X ", buf[i]);
+			else
+				fputs("   ", stdout);
+			if (i == 7 || i == 15)
+				putchar(' ');
+		}
+		for (i = 0; i < chunk; i++) {
+			c = buf[i];
+			if (c < ' ' || c > '~')
+				c = '.';
+			putchar(c);
+		}
+		putchar('\n');
+	}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	if (argc != 2) {
+		fprintf(stderr, "usage: %s server-ip\n", argv[0]);
+		exit(1);
+	}
+	server_sin.sin_family = AF_INET;
+	server_sin.sin_addr.s_addr = inet_addr(argv[1]);
+	if (server_sin.sin_addr.s_addr == INADDR_NONE) {
+		fprintf(stderr, "error: invalid IP address argument \"%s\"\n",
+			argv[1]);
+		exit(1);
+	}
+	server_sin.sin_port = htons(2775);
+	tcpsock = socket(AF_INET, SOCK_STREAM, 0);
+	if (tcpsock < 0) {
+		perror("socket");
+		exit(1);
+	}
+	setlinebuf(stdout);
+	init_stage();
+	for (;;) {
+		rx_bytes(rx_hdr, 16);
+		print_hdr();
+		preen_rx_len();
+		read_and_dump_body();
+	}
+}