view libutil/alpha_valid.c @ 47:b0cf75d0bb2d

doc/Serial-SIM-readers article written
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 21 Mar 2021 04:32:18 +0000
parents 34bbb0585cab
children
line wrap: on
line source

/*
 * This module contains functions for validating alpha fields
 * that exist in various SIM files.
 */

#include <sys/types.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>

static
validate_classic_gsm(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	u_char *dp;
	unsigned n;

	dp = data;
	for (n = 0; n < nbytes; n++) {
		if (*dp == 0xFF)
			break;
		if (*dp & 0x80)
			return(-1);
		dp++;
	}
	if (textlenp)
		*textlenp = n;
	for (; n < nbytes; n++)
		if (*dp++ != 0xFF)
			return(-1);
	return(0);
}

static
validate_ucs2_80(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	u_char *dp, *endp;

	if (nbytes < 3)
		return(-1);
	dp = data + 1;
	endp = data + nbytes;
	while (dp < endp) {
		if (dp + 1 == endp) {
			if (*dp != 0xFF)
				return(-1);
			if (textlenp)
				*textlenp = dp - data;
			return(0);
		}
		if (dp[0] == 0xFF && dp[1] == 0xFF)
			break;
		dp += 2;
	}
	if (textlenp)
		*textlenp = dp - data;
	while (dp < endp)
		if (*dp++ != 0xFF)
			return(-1);
	return(0);
}

static
validate_ucs2_81(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	u_char *dp, *endp;
	unsigned textlen;

	if (nbytes < 4)
		return(-1);
	if (!data[1])
		return(-1);
	textlen = data[1] + 3;
	if (textlen > nbytes)
		return(-1);
	if (textlenp)
		*textlenp = textlen;
	dp = data + textlen;
	endp = data + nbytes;
	while (dp < endp)
		if (*dp++ != 0xFF)
			return(-1);
	return(0);
}

static
validate_ucs2_82(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	u_char *dp, *endp;
	unsigned textlen;

	if (nbytes < 5)
		return(-1);
	if (!data[1])
		return(-1);
	textlen = data[1] + 4;
	if (textlen > nbytes)
		return(-1);
	if (textlenp)
		*textlenp = textlen;
	dp = data + textlen;
	endp = data + nbytes;
	while (dp < endp)
		if (*dp++ != 0xFF)
			return(-1);
	return(0);
}

static
validate_empty(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	u_char *dp;
	unsigned n;

	dp = data;
	for (n = 0; n < nbytes; n++)
		if (*dp++ != 0xFF)
			return(-1);
	if (textlenp)
		*textlenp = 0;
	return(0);
}

validate_alpha_field(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	if (data[0] < 0x80)
		return validate_classic_gsm(data, nbytes, textlenp);
	switch (data[0]) {
	case 0x80:
		return validate_ucs2_80(data, nbytes, textlenp);
	case 0x81:
		return validate_ucs2_81(data, nbytes, textlenp);
	case 0x82:
		return validate_ucs2_82(data, nbytes, textlenp);
	case 0xFF:
		return validate_empty(data, nbytes, textlenp);
	default:
		return -1;
	}
}