changeset 220:c798a1762c7c

smpp-test1: take strings on the command line, construct bind req
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 01 Aug 2023 23:29:38 -0800
parents 9ba474e918c0
children e1d7db9d734c
files utils/smpp-test1.c
diffstat 1 files changed, 101 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/utils/smpp-test1.c	Tue Aug 01 22:56:52 2023 -0800
+++ b/utils/smpp-test1.c	Tue Aug 01 23:29:38 2023 -0800
@@ -14,24 +14,93 @@
 #include <strings.h>
 #include <unistd.h>
 
-static const u_char bind_req[] = {
-	0x00, 0x00, 0x00, 0x23,		/* command_length */
-	0x00, 0x00, 0x00, 0x09,		/* command_id: bind_transceiver */
-	0x00, 0x00, 0x00, 0x00,		/* command_status */
-	0x00, 0x00, 0x00, 0x01,		/* sequence_number */
-	'G','S','M','-','S','M','S','C',0,	/* system_id */
-	0,				/* password: empty string */
-	'S','M','P','P',0,		/* system_type */
-	0x34,				/* interface_version */
-	0, 0, 0				/* empty address params */
-};
-
 static int tcpsock;
 static struct sockaddr_in server_sin;
+static u_char bind_req[64];
+static unsigned bind_req_len;
+static char system_id[16], password[9];
 static u_char rx_hdr[16];
 static unsigned rx_pkt_len;
 
 static void
+construct_bind_req()
+{
+	u_char *dp;
+	unsigned slen;
+
+	dp = bind_req + 4;	/* length will be filled last */
+	/* command_id */
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0x09;		/* bind_transceiver */
+	/* empty command_status */
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0;
+	/* sequence_number */
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 1;
+	/* system_id */
+	slen = strlen(system_id) + 1;
+	bcopy(system_id, dp, slen);
+	dp += slen;
+	/* password */
+	slen = strlen(password) + 1;
+	bcopy(password, dp, slen);
+	dp += slen;
+	/* system_type */
+	strcpy(dp, "SMPP");
+	dp += 5;
+	/* interface_version */
+	*dp++ = 0x34;
+	/* addr_ton */
+	*dp++ = 0;
+	/* addr_npi */
+	*dp++ = 0;
+	/* address_range */
+	*dp++ = 0;
+	bind_req_len = dp - bind_req;
+	bind_req[0] = bind_req_len >> 24;
+	bind_req[1] = bind_req_len >> 16;
+	bind_req[2] = bind_req_len >> 8;
+	bind_req[3] = bind_req_len;
+}
+
+static void
+print_bind_req()
+{
+	unsigned off, chunk;
+	int i, c;
+
+	printf("Constructed bind request of %u bytes\n", bind_req_len);
+	for (off = 0; off < bind_req_len; off += chunk) {
+		chunk = bind_req_len - off;
+		if (chunk > 16)
+			chunk = 16;
+		printf("%02X:  ", off);
+		for (i = 0; i < 16; i++) {
+			if (i < chunk)
+				printf("%02X ", bind_req[off + i]);
+			else
+				fputs("   ", stdout);
+			if (i == 7 || i == 15)
+				putchar(' ');
+		}
+		for (i = 0; i < chunk; i++) {
+			c = bind_req[off + i];
+			if (c < ' ' || c > '~')
+				c = '.';
+			putchar(c);
+		}
+		putchar('\n');
+	}
+}
+
+static void
 init_stage()
 {
 	int rc;
@@ -42,8 +111,8 @@
 		perror("connect");
 		exit(1);
 	}
-	rc = write(tcpsock, bind_req, sizeof bind_req);
-	if (rc != sizeof bind_req) {
+	rc = write(tcpsock, bind_req, bind_req_len);
+	if (rc != bind_req_len) {
 		perror("write");
 		exit(1);
 	}
@@ -127,8 +196,9 @@
 main(argc, argv)
 	char **argv;
 {
-	if (argc != 2) {
-		fprintf(stderr, "usage: %s server-ip\n", argv[0]);
+	if (argc < 3 || argc > 4) {
+		fprintf(stderr, "usage: %s server-ip system-id [password]\n",
+			argv[0]);
 		exit(1);
 	}
 	server_sin.sin_family = AF_INET;
@@ -139,12 +209,26 @@
 		exit(1);
 	}
 	server_sin.sin_port = htons(2775);
+	if (strlen(argv[2]) > 15) {
+		fprintf(stderr, "error: system-id string is too long\n");
+		exit(1);
+	}
+	strcpy(system_id, argv[2]);
+	if (argv[3]) {
+		if (strlen(argv[3]) > 8) {
+			fprintf(stderr, "error: password string is too long\n");
+			exit(1);
+		}
+		strcpy(password, argv[3]);
+	}
+	construct_bind_req();
+	setlinebuf(stdout);
+	print_bind_req();
 	tcpsock = socket(AF_INET, SOCK_STREAM, 0);
 	if (tcpsock < 0) {
 		perror("socket");
 		exit(1);
 	}
-	setlinebuf(stdout);
 	init_stage();
 	for (;;) {
 		rx_bytes(rx_hdr, 16);