view utils/smpp-test1.c @ 219:9ba474e918c0

smpp-test1: try sending some ID strings
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 01 Aug 2023 22:56:52 -0800
parents 211a043a385f
children c798a1762c7c
line wrap: on
line source

/*
 * 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, 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 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();
	}
}