added win32 support for MINGW32-compiler/cross-compiler
[librfid] / utils / librfid-tool.c
1 /* librfid-tool - a small command-line tool for librfid testing
2  *
3  * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License version 2 
7  *  as published by the Free Software Foundation
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24 /*#include <libgen.h>*/
25
26 #define _GNU_SOURCE
27 #include <getopt.h>
28
29 #include <librfid/rfid.h>
30 #include <librfid/rfid_scan.h>
31 #include <librfid/rfid_reader.h>
32 #include <librfid/rfid_layer2.h>
33 #include <librfid/rfid_protocol.h>
34
35 #include <librfid/rfid_protocol_mifare_classic.h>
36 #include <librfid/rfid_protocol_mifare_ul.h>
37
38 #include "librfid-tool.h"
39
40
41 static int select_mf(void)
42 {
43         unsigned char cmd[] = { 0x00, 0xa4, 0x00, 0x00, 0x02, 0x3f, 0x00, 0x00 };
44         unsigned char ret[256];
45         unsigned int rlen = sizeof(ret);
46
47         int rv;
48
49         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
50         if (rv < 0)
51                 return rv;
52
53         printf("%d: [%s]\n", rlen, hexdump(ret, rlen));
54
55         return 0;
56 }
57
58
59 static int iso7816_get_challenge(unsigned char len)
60 {
61         unsigned char cmd[] = { 0x00, 0x84, 0x00, 0x00, 0x08 };
62         unsigned char ret[256];
63         unsigned int rlen = sizeof(ret);
64
65         cmd[4] = len;
66
67         int rv;
68
69         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
70         if (rv < 0)
71                 return rv;
72
73         printf("%d: [%s]\n", rlen, hexdump(ret, rlen));
74
75         return 0;
76 }
77
78 int
79 iso7816_select_application(void)
80 {
81         unsigned char cmd[] = { 0x00, 0xa4, 0x04, 0x0c, 0x07,
82                        0xa0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01 };
83         unsigned char resp[7];
84         unsigned int rlen = sizeof(resp);
85
86         int rv;
87
88         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
89         if (rv < 0)
90                 return rv;
91
92         /* FIXME: parse response */
93         printf("%s\n", hexdump(resp, rlen));
94
95         return 0;
96 }
97
98 int
99 iso7816_select_ef(u_int16_t fid)
100 {
101         unsigned char cmd[7] = { 0x00, 0xa4, 0x02, 0x0c, 0x02, 0x00, 0x00 };
102         unsigned char resp[7];
103         unsigned int rlen = sizeof(resp);
104
105         int rv;
106
107         cmd[5] = (fid >> 8) & 0xff;
108         cmd[6] = fid & 0xff;
109
110         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
111         if (rv < 0)
112                 return rv;
113
114         /* FIXME: parse response */
115         printf("%s\n", hexdump(resp, rlen));
116
117         return 0;
118 }
119
120 int
121 iso7816_read_binary(unsigned char *buf, unsigned int *len)
122 {
123         unsigned char cmd[] = { 0x00, 0xb0, 0x00, 0x00, 0x00 };
124         unsigned char resp[256];
125         unsigned int rlen = sizeof(resp);
126         
127         int rv;
128
129         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
130         if (rv < 0)
131                 return rv;
132
133         printf("%s\n", hexdump(resp, rlen));
134
135         /* FIXME: parse response, determine whether we need additional reads */
136
137         /* FIXME: copy 'len' number of response bytes to 'buf' */
138         return 0;
139 }
140
141 /* wrapper function around SELECT EF and READ BINARY */
142 int
143 iso7816_read_ef(u_int16_t fid, unsigned char *buf, unsigned int *len)
144 {
145         int rv;
146
147         rv = iso7816_select_ef(fid);
148         if (rv < 0)
149                 return rv;
150
151         return iso7816_read_binary(buf, len);
152 }
153
154 /* mifare ultralight helpers */
155 int
156 mifare_ulight_write(struct rfid_protocol_handle *ph)
157 {
158         unsigned char buf[4] = { 0xa1, 0xa2, 0xa3, 0xa4 };
159
160         return rfid_protocol_write(ph, 10, buf, 4);
161 }
162
163 int
164 mifare_ulight_blank(struct rfid_protocol_handle *ph)
165 {
166         unsigned char buf[4] = { 0x00, 0x00, 0x00, 0x00 };
167         int i, ret;
168
169         for (i = 4; i <= MIFARE_UL_PAGE_MAX; i++) {
170                 ret = rfid_protocol_write(ph, i, buf, 4);
171                 if (ret < 0)
172                         return ret;
173         }
174         return 0;
175 }
176
177 static int
178 mifare_ulight_read(struct rfid_protocol_handle *ph)
179 {
180         unsigned char buf[20];
181         unsigned int len = sizeof(buf);
182         int ret;
183         int i;
184
185         for (i = 0; i <= MIFARE_UL_PAGE_MAX; i++) {
186                 ret = rfid_protocol_read(ph, i, buf, &len);
187                 if (ret < 0)
188                         return ret;
189
190                 printf("Page 0x%x: %s\n", i, hexdump(buf, 4));
191         }
192         return 0;
193 }
194
195 /* mifare classic helpers */
196 static int
197 mifare_classic_read_sector(struct rfid_protocol_handle *ph, int sector)
198 {
199         unsigned char buf[20];
200         unsigned int len = sizeof(buf);
201         int ret;
202         int block;
203
204         /* FIXME: make this work for sectors > 31 */
205         printf("Reading sector %u\n", sector);
206
207         for (block = sector*4; block < sector*4+4; block++) {
208                 printf("Reading block %u: ", block);
209                 ret = rfid_protocol_read(ph, block, buf, &len);
210                 if(ret == -ETIMEDOUT)
211                         fprintf(stderr, "TIMEOUT\n");
212                 if (ret < 0) {
213                         printf("Error %d reading\n", ret);
214                         return ret;
215                 }
216
217                 printf("Page 0x%x: %s\n", block, hexdump(buf, len));
218         }
219         return 0;
220 }
221
222 static char *proto_names[] = {
223         [RFID_PROTOCOL_TCL] = "tcl",
224         [RFID_PROTOCOL_MIFARE_UL] = "mifare-ultralight",
225         [RFID_PROTOCOL_MIFARE_CLASSIC] = "mifare-classic",
226 };
227
228 static int proto_by_name(const char *name)
229 {
230         int i;
231
232         for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
233                 if (proto_names[i] == NULL)
234                         continue;
235                 if (!strcasecmp(name, proto_names[i]))
236                         return i;
237         }
238         return -1;
239 }
240
241 static char *l2_names[] = {
242         [RFID_LAYER2_ISO14443A] = "iso14443a",
243         [RFID_LAYER2_ISO14443B] = "iso14443b",
244         [RFID_LAYER2_ISO15693] = "iso15693",
245 };
246
247 static int l2_by_name(const char *name)
248 {
249         int i;
250
251         for (i = 0; i < ARRAY_SIZE(l2_names); i++) {
252                 if (l2_names[i] == NULL)
253                         continue;
254                 if (!strcasecmp(name, l2_names[i]))
255                         return i;
256         }
257         return -1;
258 }
259
260 static void do_scan(void)
261 {
262         int rc;
263         unsigned int size;
264         unsigned int size_len = sizeof(size);
265
266         printf("scanning for RFID token...\n");
267         rc = rfid_scan(rh, &l2h, &ph);
268         if (rc >= 2) {
269                 unsigned char uid_buf[16];
270                 unsigned int uid_len = sizeof(uid_buf);
271                 rfid_layer2_getopt(l2h, RFID_OPT_LAYER2_UID, &uid_buf,
272                                    &uid_len);
273                 printf("Layer 2 success (%s): %s\n", rfid_layer2_name(l2h),
274                         hexdump(uid_buf, uid_len));
275         }
276         if (rc >= 3) {
277                 printf("Protocol success (%s)\n", rfid_protocol_name(ph));
278
279                 if (rfid_protocol_getopt(ph, RFID_OPT_PROTO_SIZE, 
280                                          &size, &size_len) == 0)
281                         printf("Size: %u bytes\n", size);
282         }
283 }
284
285 #define OPTION_OFFSET 256
286
287 static struct option original_opts[] = {
288         { "help", 0, 0, 'h' },
289         { "layer2", 1, 0, 'l' },
290         { "protocol", 1, 0, 'p' },
291         { "scan", 0, 0, 's' },
292         { "scan-loop", 0, 0, 'S' },
293         {0, 0, 0, 0}
294 };
295
296 /* module / option merging code */
297 static struct option *opts = original_opts;
298 static unsigned int global_option_offset = 0;
299
300 static char *program_name;
301 static char *program_version = LIBRFID_TOOL_VERSION;
302
303 static void free_opts(int reset_offset)
304 {
305         if (opts != original_opts) {
306                 free(opts);
307                 opts = original_opts;
308                 if (reset_offset)
309                         global_option_offset = 0;
310         }
311 }
312
313 static struct option *
314 merge_options(struct option *oldopts, const struct option *newopts,
315               unsigned int *option_offset)
316 {
317         unsigned int num_old, num_new, i;
318         struct option *merge;
319
320         for (num_old = 0; oldopts[num_old].name; num_old++);
321         for (num_new = 0; oldopts[num_new].name; num_new++);
322
323         global_option_offset += OPTION_OFFSET;
324         *option_offset = global_option_offset;
325
326         merge = malloc(sizeof(struct option) * (num_new + num_old + 1));
327         memcpy(merge, oldopts, num_old * sizeof(struct option));
328         free_opts(0); /* Release previous options merged if any */
329         for (i = 0; i < num_new; i++) {
330                 merge[num_old + i] = newopts[i];
331                 merge[num_old + i].val += *option_offset;
332         }
333         memset(merge + num_old + num_new, 0, sizeof(struct option));
334
335         return merge;
336 }
337
338 struct rfidtool_module *find_module(const char *name)
339 {
340         return NULL;
341 }
342
343 void register_module(struct rfidtool_module *me)
344 {
345         struct rfidtool_module *old;
346
347         if (strcmp(me->version, program_version) != 0) {
348                 fprintf(stderr, "%s: target `%s' v%s (I'm v%s).\n",
349                         program_name, me->name, me->version, program_version);
350                 exit(1);
351         }
352
353         old = find_module(me->name);
354         if (old) {
355                 fprintf(stderr, "%s: target `%s' already registered.\n",
356                         program_name, me->name);
357                 exit(1);
358         }
359 }
360
361 static void help(void)
362 {
363         printf( " -s    --scan          scan until first RFID tag is found\n"
364                 " -S    --scan-loop     endless scanning loop\n" 
365                 " -p    --protocol      {tcl,mifare-ultralight,mifare-classic}\n"
366                 " -l    --layer2        {iso14443a,iso14443b,iso15693}\n"
367                 " -h    --help\n");
368 }
369
370 int main(int argc, char **argv)
371 {
372         int rc;
373         char buf[0x100];
374         int i, len, protocol = -1, layer2 = -1;
375
376 #ifdef  __MINGW32__
377         program_name = argv[0];
378 #else /*__MINGW32__*/
379         program_name = basename(argv[0]);
380 #endif/*__MINGW32__*/
381         
382         printf("%s - (C) 2006 by Harald Welte\n"
383                "This program is Free Software and has "
384                "ABSOLUTELY NO WARRANTY\n\n", program_name);
385
386         printf("initializing librfid\n");
387         rfid_init();
388
389         while (1) {
390                 int c, option_index = 0;
391                 c = getopt_long(argc, argv, "hp:l:sS", opts, &option_index);
392                 if (c == -1)
393                         break;
394
395                 switch (c) {
396                 case 's':
397                         if (reader_init() < 0)
398                                 exit(1);
399                         do_scan();
400                         exit(0);
401                         break;
402                 case 'S':
403                         if (reader_init() < 0)
404                                 exit(1);
405                         while (1) 
406                                 do_scan();
407                         exit(0);
408                         break;
409                 case 'p':
410                         protocol = proto_by_name(optarg);
411                         if (protocol < 0) {
412                                 fprintf(stderr, "unknown protocol `%s'\n", 
413                                         optarg);
414                                 exit(2);
415                         }
416                         break;
417                 case 'l':
418                         layer2 = l2_by_name(optarg);
419                         if (layer2 < 0) {
420                                 fprintf(stderr, "unknown layer2 `%s'\n",
421                                         optarg);
422                                 exit(2);
423                         }
424                         break;
425                 case 'h':
426                         help();
427                         exit(0);
428                         break;
429                 }
430         }
431
432         switch (protocol) {
433         case RFID_PROTOCOL_MIFARE_UL:
434         case RFID_PROTOCOL_MIFARE_CLASSIC:
435                 layer2 = RFID_LAYER2_ISO14443A;
436                 break;
437         case -1:
438                 fprintf(stderr, "you have to specify --protocol\n");
439                 exit(2);
440         }
441
442         if (layer2 < 0) {
443                 fprintf(stderr, "you have to specify --layer2\n");
444                 exit(2);
445         }
446         
447         if (reader_init() < 0)
448                 exit(1);
449
450         if (l2_init(layer2) < 0)
451                 exit(1);
452
453         if (l3_init(protocol) < 0)
454                 exit(1);
455
456         switch (protocol) {
457
458         case RFID_PROTOCOL_TCL:
459                 printf("Protocol T=CL\n");
460                 /* we've established T=CL at this point */
461                 printf("selecting Master File\n");
462                 rc = select_mf();
463                 if (rc < 0) {
464                         printf("error selecting MF\n");
465                         break;
466                 }
467
468                 printf("Getting random challenge, length 255\n");
469                 rc = iso7816_get_challenge(0xff);
470                 if (rc < 0) {
471                         printf("error getting random challenge\n");
472                         break;
473                 }
474
475                 printf("selecting Passport application\n");
476                 rc = iso7816_select_application();
477                 if (rc < 0) {
478                         printf("error selecting passport application\n");
479                         break;
480                 }
481
482                 printf("selecting EF 0x1e\n");
483                 rc = iso7816_select_ef(0x011e);
484                 if (rc < 0) {
485                         printf("error selecting EF 0x1e\n");
486                         break;
487                 }
488
489                 printf("selecting EF 0x01\n");
490                 rc = iso7816_select_ef(0x0101);
491                 if (rc < 0) {
492                         printf("error selecting EF 0x01\n");
493                         break;
494                 }
495
496                 while (1) {
497                         printf("reading EF1\n");
498                         len = sizeof(buf);
499                         printf("reading ef\n");
500                         rc = iso7816_read_binary(buf, &len);
501                         if (rc < 0) {
502                                 printf("error reading EF\n");
503                                 break;
504                         }
505                 }
506 #if 0
507                 for (i = 0; i < 4; i++)
508                         iso7816_get_challenge(0xff);
509 #endif
510                 break;
511         case RFID_PROTOCOL_MIFARE_UL:
512                 printf("Protocol Mifare Ultralight\n");
513                 mifare_ulight_read(ph);
514 #if 0
515                 mifare_ulight_blank(ph);
516                 mifare_ulight_write(ph);
517                 mifare_ulight_read(ph);
518 #endif
519                 break;
520         case RFID_PROTOCOL_MIFARE_CLASSIC:
521                 printf("Protocol Mifare Classic\n");
522                 {
523                         int sector;
524                         for (sector = 0; sector < 31; sector++) {
525                                 printf("Authenticating sector %u: ", sector);
526                                 fflush(stdout);
527                                 rc = mfcl_set_key(ph, MIFARE_CL_KEYA_DEFAULT_INFINEON);
528                                 if (rc < 0) {
529                                         printf("key format error\n");
530                                         exit(1);
531                                 }
532                                 rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, sector*4);
533                                 if (rc < 0) {
534                                         printf("mifare auth error\n");
535                                         exit(1);
536                                 } else 
537                                         printf("mifare auth succeeded!\n");
538
539                                 mifare_classic_read_sector(ph, sector);
540                         }
541                 }
542                 break;
543         default:
544                 printf("unknown protocol\n");
545                 exit(1);
546                 break;
547         }
548
549         rfid_reader_close(rh);
550         
551         exit(0);
552 }