view rvinterf/lowlevel/rviftmode.c @ 1011:6d9b10633f10 default tip

etmsync Pirelli IMEI retrieval: fix poor use of printf() Bug reported by Vadim Yanitskiy <fixeria@osmocom.org>: the construct where a static-allocated string was passed to printf() without any format arguments causes newer compilers to report a security problem. Given that formatted output is not needed here, just fixed string output, change printf() to fputs(), and direct the error message to stderr while at it.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 23 May 2024 17:29:57 +0000
parents ec5f51d33fdc
children
line wrap: on
line source

/*
 * This module is for rvinterf only.  Whenever we send or receive Test Mode
 * packets, we should be a little more intelligent about how we display and
 * log them.  By default we only print a one-line summary, and in verbose mode
 * we also emit a full hex dump.
 */

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include "../include/etm.h"
#include "../include/tm3.h"
#include "../include/tmffs2.h"

extern u_char rxpkt[];
extern size_t rxpkt_len;

extern int verbose;

extern void output_cont_logpref();

static int
verify_cksum(pkt, pktlen)
	u_char *pkt;
	unsigned pktlen;
{
	int i, c;

	c = 0;
	for (i = 1; i < pktlen; i++)
		c ^= pkt[i];
	if (c == 0)
		return(0);
	else
		return(-1);
}

static void
etm_core_classify(pkt, pktlen, outbuf)
	u_char *pkt;
	unsigned pktlen;
	char *outbuf;
{
	if (pktlen < 4) {
runt:		strcpy(outbuf, "ETM_CORE runt");
		return;
	}
	switch (pkt[2]) {
	case TMCORE_OPC_MEM:
		if (pktlen < 5)
			goto runt;
		switch (pkt[3]) {
		case 0x01:
			strcpy(outbuf, "r8");
			return;
		case 0x02:
			strcpy(outbuf, "r16");
			return;
		case 0x04:
			strcpy(outbuf, "r32");
			return;
		case 0x11:
			strcpy(outbuf, "w8");
			return;
		case 0x12:
			strcpy(outbuf, "w16");
			return;
		case 0x14:
			strcpy(outbuf, "w32");
			return;
		default:
			sprintf(outbuf, "ETM_CORE mem opcode 0x%02X", pkt[3]);
		}
		return;
	case TMCORE_OPC_ECHO:
		strcpy(outbuf, "ping");
		return;
	case TMCORE_OPC_RESET:
		strcpy(outbuf, "tgtreset");
		return;
	case TMCORE_OPC_DEBUG:
		strcpy(outbuf, "ETM_CORE debug opc");
		return;
	case TMCORE_OPC_VERSION:
		strcpy(outbuf, "version");
		return;
	case TMCORE_OPC_CODEC_RD:
		strcpy(outbuf, "abbr");
		return;
	case TMCORE_OPC_CODEC_WR:
		strcpy(outbuf, "abbw");
		return;
	case TMCORE_OPC_DIEID:
		strcpy(outbuf, "dieid");
		return;
	default:
		sprintf(outbuf, "ETM_CORE opcode 0x%02X", pkt[2]);
	}
}

static void
tmffs2_cmd_classify(pkt, pktlen, outbuf)
	u_char *pkt;
	unsigned pktlen;
	char *outbuf;
{
	if (pktlen < 4) {
		strcpy(outbuf, "ETM_FFS2 runt");
		return;
	}
	switch (pkt[2]) {
	case TMFFS_FORMAT:
		strcpy(outbuf, "FFS2 format");
		return;
	case TMFFS_PREFORMAT:
		strcpy(outbuf, "FFS2 preformat");
		return;
	case TMFFS_MKDIR:
		strcpy(outbuf, "FFS2 mkdir");
		return;
	case TMFFS_OPENDIR:
		strcpy(outbuf, "FFS2 opendir");
		return;
	case TMFFS_READDIR:
		strcpy(outbuf, "FFS2 readdir");
		return;
	case TMFFS_REMOVE:
		strcpy(outbuf, "FFS2 remove");
		return;
	case TMFFS_RENAME:
		strcpy(outbuf, "FFS2 rename");
		return;
	case TMFFS_XLSTAT:
		strcpy(outbuf, "FFS2 xlstat");
		return;
	case TMFFS_SYMLINK:
		strcpy(outbuf, "FFS2 symlink");
		return;
	case TMFFS_READLINK:
		strcpy(outbuf, "FFS2 readlink");
		return;
	case TMFFS_OPEN:
		strcpy(outbuf, "FFS2 open");
		return;
	case TMFFS_CLOSE:
		strcpy(outbuf, "FFS2 close");
		return;
	case TMFFS_READ:
		strcpy(outbuf, "FFS2 read");
		return;
	case TMFFS_WRITE:
		strcpy(outbuf, "FFS2 write");
		return;
	case TMFFS_SEEK:
		strcpy(outbuf, "FFS2 seek");
		return;
	case TMFFS_FTRUNCATE:
		strcpy(outbuf, "FFS2 ftruncate");
		return;
	case TMFFS_TRUNCATE:
		strcpy(outbuf, "FFS2 truncate");
		return;
	case TMFFS_FILE_READ:
		strcpy(outbuf, "FFS2 fread");
		return;
	case TMFFS_FILE_WRITE:
		strcpy(outbuf, "FFS2 fwrite");
		return;
	case TMFFS_FSTAT:
		strcpy(outbuf, "FFS2 fstat");
		return;
	case TMFFS_LSTAT:
		strcpy(outbuf, "FFS2 lstat");
		return;
	case TMFFS_STAT:
		strcpy(outbuf, "FFS2 stat");
		return;
	case TMFFS_FCONTROL:
		strcpy(outbuf, "FFS2 fcontrol");
		return;
	case TMFFS_QUERY:
		strcpy(outbuf, "FFS2 query");
		return;
	case TMFFS_INIT:
		strcpy(outbuf, "FFS2 init");
		return;
	case TMFFS_EXIT:
		strcpy(outbuf, "FFS2 exit");
		return;
	case TMFFS_DIRXLSTAT:
		strcpy(outbuf, "FFS2 dirxlstat");
		return;
	case TMFFS_VERSION:
		strcpy(outbuf, "FFS2 version");
		return;
	case TMFFS_TFFS:
		strcpy(outbuf, "FFS2 tffs");
		return;
	default:
		sprintf(outbuf, "ETM_FFS2 opcode 0x%02X", pkt[2]);
	}
}

static void
audio_cmd_classify(pkt, pktlen, outbuf)
	u_char *pkt;
	unsigned pktlen;
	char *outbuf;
{
	if (pktlen < 4) {
		strcpy(outbuf, "ETM_AUDIO runt");
		return;
	}
	switch (pkt[2]) {
	case 'L':
		strcpy(outbuf, "aul");
		return;
	case 'S':
		strcpy(outbuf, "aus");
		return;
	case 'R':
		strcpy(outbuf, "aur");
		return;
	case 'W':
		strcpy(outbuf, "auw");
		return;
	default:
		sprintf(outbuf, "ETM_AUDIO opcode 0x%02X", pkt[2]);
	}
}

static void
tm_classify(pkt, pktlen, is_cmd, outbuf)
	u_char *pkt;
	unsigned pktlen;
	char *outbuf;
{
	if (pktlen < 3) {
		strcpy(outbuf, "RUNT");
		return;
	}
	if (verify_cksum(pkt, pktlen) < 0) {
		strcpy(outbuf, "BAD CKSUM");
		return;
	}
	switch (pkt[1]) {
	case ETM_CORE:
		if (is_cmd)
			etm_core_classify(pkt, pktlen, outbuf);
		else
			strcpy(outbuf, "ETM_CORE");
		return;
	case ETM_FFS1:
		strcpy(outbuf, "FFS1");
		return;
	case ETM_FFS2:
		if (is_cmd)
			tmffs2_cmd_classify(pkt, pktlen, outbuf);
		else
			strcpy(outbuf, "FFS2");
		return;
	case ETM_AUDIO:
		if (is_cmd)
			audio_cmd_classify(pkt, pktlen, outbuf);
		else
			strcpy(outbuf, "ETM_AUDIO");
		return;
	case ETM_BSIM:
		strcpy(outbuf, "BSIM");
		return;
	/* TM3 */
	case MEM_READ:
		strcpy(outbuf, "omr");
		return;
	case MEM_WRITE:
		strcpy(outbuf, "omw");
		return;
	case CODEC_READ:
		strcpy(outbuf, "oabbr");
		return;
	case CODEC_WRITE:
		strcpy(outbuf, "oabbw");
		return;
	/* L1TM */
	case TM_INIT:
		strcpy(outbuf, "tminit");
		return;
	case TM_MODE_SET:
		strcpy(outbuf, "tms");
		return;
	case VERSION_GET:
		strcpy(outbuf, "tm3ver");
		return;
	case RF_ENABLE:
		strcpy(outbuf, "rfe");
		return;
	case STATS_READ:
		strcpy(outbuf, "sr");
		return;
	case STATS_CONFIG_WRITE:
		strcpy(outbuf, "scw");
		return;
	case STATS_CONFIG_READ:
		strcpy(outbuf, "scr");
		return;
	case RF_PARAM_WRITE:
		strcpy(outbuf, "rfpw");
		return;
	case RF_PARAM_READ:
		strcpy(outbuf, "rfpr");
		return;
	case RF_TABLE_WRITE:
		strcpy(outbuf, "rftw");
		return;
	case RF_TABLE_READ:
		strcpy(outbuf, "rftr");
		return;
	case RX_PARAM_WRITE:
		strcpy(outbuf, "rxpw");
		return;
	case RX_PARAM_READ:
		strcpy(outbuf, "rxpr");
		return;
	case TX_PARAM_WRITE:
		strcpy(outbuf, "txpw");
		return;
	case TX_PARAM_READ:
		strcpy(outbuf, "txpr");
		return;
	case TX_TEMPLATE_WRITE:
		strcpy(outbuf, "ttw");
		return;
	case TX_TEMPLATE_READ:
		strcpy(outbuf, "ttr");
		return;
	case MISC_PARAM_WRITE:
		strcpy(outbuf, "mpw");
		return;
	case MISC_PARAM_READ:
		strcpy(outbuf, "mpr");
		return;
	case MISC_ENABLE:
		strcpy(outbuf, "me");
		return;
	default:
		sprintf(outbuf, "mid 0x%02X", pkt[1]);
	}
}

void
log_sent_tm(pkt, pktlen)
	u_char *pkt;
{
	char summary[32], headline[80];

	tm_classify(pkt, pktlen, 1, summary);
	sprintf(headline, "Sent Test Mode cmd (%s)", summary);
	output_line(headline);
	if (verbose >= 1)
		packet_hex_dump(pkt, pktlen, output_cont_logpref);
}

void
print_tm_output_new()
{
	char summary[32], headline[80];

	tm_classify(rxpkt, (unsigned) rxpkt_len, 0, summary);
	sprintf(headline, "Rx Test Mode resp (%s)", summary);
	output_line(headline);
	if (verbose >= 1)
		packet_hex_dump(rxpkt, (unsigned) rxpkt_len,
				output_cont_logpref);
}