FreeCalypso > hg > fc-sim-tools
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); +}