diff utils/fcsim1-mkprov.c @ 35:26d2ef843a99

fcsim1-mkprov utility implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 17 Mar 2021 04:51:53 +0000
parents
children 38c14fa89937
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/fcsim1-mkprov.c	Wed Mar 17 04:51:53 2021 +0000
@@ -0,0 +1,164 @@
+/*
+ * This utility is the provisioning data generator for FCSIM1 cards.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static u_char iccid_bin[19], imsi_bin[15], msisdn_bin[20];
+static int msisdn_set, msisdn_plus;
+static unsigned num_cards = 1, access_class, msisdn_digits;
+static char *random_file = "/dev/urandom";
+static int random_fd;
+
+static void
+set_iccid(arg)
+	char *arg;
+{
+	int rc;
+
+	rc = parse_decimal_shorthand(arg, iccid_bin, 18);
+	if (rc < 0)
+		exit(1);	/* error msg already printed */
+}
+
+static void
+set_imsi(arg)
+	char *arg;
+{
+	int rc;
+
+	rc = parse_decimal_shorthand(arg, imsi_bin, 15);
+	if (rc < 0)
+		exit(1);	/* error msg already printed */
+}
+
+static void
+set_msisdn(arg)
+	char *arg;
+{
+	int rc;
+
+	if (*arg == '+') {
+		msisdn_plus = 1;
+		arg++;
+	}
+	rc = parse_decimal_string_arg(arg, msisdn_bin, 20);
+	if (rc < 0)
+		exit(1);	/* error msg already printed */
+	msisdn_digits = rc;
+	msisdn_set = 1;
+}
+
+static void
+parse_cmdline(argc, argv)
+	char **argv;
+{
+	extern int optind;
+	extern char *optarg;
+	int c;
+
+	while ((c = getopt(argc, argv, "a:m:n:r:")) != EOF) {
+		switch (c) {
+		case 'a':
+			if (optarg[0] < '0' || optarg[0] > '9' || optarg[1]) {
+				fprintf(stderr, "error: invalid -a argument\n");
+				exit(1);
+			}
+			access_class = optarg[0] - '0';
+			continue;
+		case 'm':
+			set_msisdn(optarg);
+			continue;
+		case 'n':
+			num_cards = atoi(optarg);
+			continue;
+		case 'r':
+			random_file = optarg;
+			continue;
+		case '?':
+		default:
+usage:			fprintf(stderr,
+				"usage: %s [options] start-iccid start-imsi\n",
+				argv[0]);
+			exit(1);
+		}
+	}
+	if (argc - optind != 2)
+		goto usage;
+	set_iccid(argv[optind]);
+	set_imsi(argv[optind+1]);
+}
+
+static void
+get_random_ki(strbuf)
+	char *strbuf;
+{
+	u_char bin[8];
+	char *dp;
+	unsigned n;
+	int rc;
+
+	rc = read(random_fd, bin, 8);
+	if (rc != 8) {
+		fprintf(stderr, "error reading from %s\n", random_file);
+		exit(1);
+	}
+	dp = strbuf;
+	for (n = 0; n < 8; n++) {
+		sprintf(dp, "%02X", bin[n]);
+		dp += 2;
+	}
+	*dp = '\0';
+}
+
+static void
+make_one_card()
+{
+	unsigned acc_mask;
+	char iccid_str[20], imsi_str[16], ki_str[33];
+	char msisdn_str[21];
+
+	nibbles_to_ascii(iccid_bin, 19, iccid_str);
+	nibbles_to_ascii(imsi_bin, 15, imsi_str);
+	acc_mask = 1 << access_class;
+	get_random_ki(ki_str);
+	printf("ICCID=%s IMSI=%s ACC=%04X Ki=%s", iccid_str, imsi_str,
+		acc_mask, ki_str);
+	if (msisdn_set) {
+		fputs(" MSISDN=", stdout);
+		if (msisdn_plus)
+			putchar('+');
+		nibbles_to_ascii(msisdn_bin, msisdn_digits, msisdn_str);
+		fputs(msisdn_str, stdout);
+	}
+	putchar('\n');
+}
+
+main(argc, argv)
+	char **argv;
+{
+	unsigned n;
+
+	parse_cmdline(argc, argv);
+	random_fd = open(random_file, O_RDONLY);
+	if (random_fd < 0) {
+		perror(random_file);
+		exit(1);
+	}
+	for (n = 0; n < num_cards; n++) {
+		iccid_bin[18] = compute_iccid_luhn(iccid_bin);
+		make_one_card();
+		decimal_string_increment(iccid_bin, 18);
+		decimal_string_increment(imsi_bin, 15);
+		if (msisdn_set)
+			decimal_string_increment(msisdn_bin, msisdn_digits);
+		access_class++;
+		if (access_class >= 10)
+			access_class = 0;
+	}
+	exit(0);
+}