comparison 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
comparison
equal deleted inserted replaced
34:e0a6111705b3 35:26d2ef843a99
1 /*
2 * This utility is the provisioning data generator for FCSIM1 cards.
3 */
4
5 #include <sys/types.h>
6 #include <sys/file.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10
11 static u_char iccid_bin[19], imsi_bin[15], msisdn_bin[20];
12 static int msisdn_set, msisdn_plus;
13 static unsigned num_cards = 1, access_class, msisdn_digits;
14 static char *random_file = "/dev/urandom";
15 static int random_fd;
16
17 static void
18 set_iccid(arg)
19 char *arg;
20 {
21 int rc;
22
23 rc = parse_decimal_shorthand(arg, iccid_bin, 18);
24 if (rc < 0)
25 exit(1); /* error msg already printed */
26 }
27
28 static void
29 set_imsi(arg)
30 char *arg;
31 {
32 int rc;
33
34 rc = parse_decimal_shorthand(arg, imsi_bin, 15);
35 if (rc < 0)
36 exit(1); /* error msg already printed */
37 }
38
39 static void
40 set_msisdn(arg)
41 char *arg;
42 {
43 int rc;
44
45 if (*arg == '+') {
46 msisdn_plus = 1;
47 arg++;
48 }
49 rc = parse_decimal_string_arg(arg, msisdn_bin, 20);
50 if (rc < 0)
51 exit(1); /* error msg already printed */
52 msisdn_digits = rc;
53 msisdn_set = 1;
54 }
55
56 static void
57 parse_cmdline(argc, argv)
58 char **argv;
59 {
60 extern int optind;
61 extern char *optarg;
62 int c;
63
64 while ((c = getopt(argc, argv, "a:m:n:r:")) != EOF) {
65 switch (c) {
66 case 'a':
67 if (optarg[0] < '0' || optarg[0] > '9' || optarg[1]) {
68 fprintf(stderr, "error: invalid -a argument\n");
69 exit(1);
70 }
71 access_class = optarg[0] - '0';
72 continue;
73 case 'm':
74 set_msisdn(optarg);
75 continue;
76 case 'n':
77 num_cards = atoi(optarg);
78 continue;
79 case 'r':
80 random_file = optarg;
81 continue;
82 case '?':
83 default:
84 usage: fprintf(stderr,
85 "usage: %s [options] start-iccid start-imsi\n",
86 argv[0]);
87 exit(1);
88 }
89 }
90 if (argc - optind != 2)
91 goto usage;
92 set_iccid(argv[optind]);
93 set_imsi(argv[optind+1]);
94 }
95
96 static void
97 get_random_ki(strbuf)
98 char *strbuf;
99 {
100 u_char bin[8];
101 char *dp;
102 unsigned n;
103 int rc;
104
105 rc = read(random_fd, bin, 8);
106 if (rc != 8) {
107 fprintf(stderr, "error reading from %s\n", random_file);
108 exit(1);
109 }
110 dp = strbuf;
111 for (n = 0; n < 8; n++) {
112 sprintf(dp, "%02X", bin[n]);
113 dp += 2;
114 }
115 *dp = '\0';
116 }
117
118 static void
119 make_one_card()
120 {
121 unsigned acc_mask;
122 char iccid_str[20], imsi_str[16], ki_str[33];
123 char msisdn_str[21];
124
125 nibbles_to_ascii(iccid_bin, 19, iccid_str);
126 nibbles_to_ascii(imsi_bin, 15, imsi_str);
127 acc_mask = 1 << access_class;
128 get_random_ki(ki_str);
129 printf("ICCID=%s IMSI=%s ACC=%04X Ki=%s", iccid_str, imsi_str,
130 acc_mask, ki_str);
131 if (msisdn_set) {
132 fputs(" MSISDN=", stdout);
133 if (msisdn_plus)
134 putchar('+');
135 nibbles_to_ascii(msisdn_bin, msisdn_digits, msisdn_str);
136 fputs(msisdn_str, stdout);
137 }
138 putchar('\n');
139 }
140
141 main(argc, argv)
142 char **argv;
143 {
144 unsigned n;
145
146 parse_cmdline(argc, argv);
147 random_fd = open(random_file, O_RDONLY);
148 if (random_fd < 0) {
149 perror(random_file);
150 exit(1);
151 }
152 for (n = 0; n < num_cards; n++) {
153 iccid_bin[18] = compute_iccid_luhn(iccid_bin);
154 make_one_card();
155 decimal_string_increment(iccid_bin, 18);
156 decimal_string_increment(imsi_bin, 15);
157 if (msisdn_set)
158 decimal_string_increment(msisdn_bin, msisdn_digits);
159 access_class++;
160 if (access_class >= 10)
161 access_class = 0;
162 }
163 exit(0);
164 }