-/* -*- linux-c -*-
+/* librfid-tool - a small command-line tool for librfid testing
+ *
+ * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
+
+#define _GNU_SOURCE
+#include <getopt.h>
#include <librfid/rfid.h>
+#include <librfid/rfid_scan.h>
#include <librfid/rfid_reader.h>
#include <librfid/rfid_layer2.h>
#include <librfid/rfid_protocol.h>
#include <librfid/rfid_protocol_mifare_classic.h>
#include <librfid/rfid_protocol_mifare_ul.h>
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
static const char *
hexdump(const void *data, unsigned int len)
{
static struct rfid_layer2_handle *l2h;
static struct rfid_protocol_handle *ph;
-static int init()
-{
- unsigned char buf[0x3f];
- int rc;
-
- printf("initializing librfid\n");
- rfid_init();
-
+static int reader() {
printf("opening reader handle\n");
rh = rfid_reader_open(NULL, RFID_READER_CM5121);
if (!rh) {
- fprintf(stderr, "error, no cm5121 handle\n");
- return -1;
+ fprintf(stderr, "No Omnikey Cardman 5121 found\n");
+ rh = rfid_reader_open(NULL, RFID_READER_OPENPCD);
+ if (!rh) {
+ fprintf(stderr, "No OpenPCD found either\n");
+ return -1;
+ }
}
+ return 0;
+}
+static int init(int layer2)
+{
+ unsigned char buf[0x3f];
+ int rc;
+
printf("opening layer2 handle\n");
- l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443A);
- //l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443B);
+ l2h = rfid_layer2_init(rh, layer2);
if (!l2h) {
fprintf(stderr, "error during iso14443a_init\n");
return -1;
int rv;
- rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
+ rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
if (rv < 0)
return rv;
int rv;
- rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
+ rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
if (rv < 0)
return rv;
int rv;
- rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
+ rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
if (rv < 0)
return rv;
cmd[5] = (fid >> 8) & 0xff;
cmd[6] = fid & 0xff;
- rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
+ rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
if (rv < 0)
return rv;
int rv;
- rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
+ rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
if (rv < 0)
return rv;
for (block = sector*4; block < sector*4+4; block++) {
printf("reading block %u\n", block);
ret = rfid_protocol_read(ph, block, buf, &len);
+ if(ret == -ETIMEDOUT)
+ fprintf(stderr, "TIMEOUT\n");
if (ret < 0)
return ret;
return 0;
}
+static char *proto_names[] = {
+ [RFID_PROTOCOL_TCL] = "tcl",
+ [RFID_PROTOCOL_MIFARE_UL] = "mifare-ultralight",
+ [RFID_PROTOCOL_MIFARE_CLASSIC] = "mifare-classic",
+};
+
+static int proto_by_name(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
+ if (proto_names[i] == NULL)
+ continue;
+ if (!strcasecmp(name, proto_names[i]))
+ return i;
+ }
+ return -1;
+}
+
+static char *l2_names[] = {
+ [RFID_LAYER2_ISO14443A] = "iso14443a",
+ [RFID_LAYER2_ISO14443B] = "iso14443b",
+ [RFID_LAYER2_ISO15693] = "iso15693",
+};
+
+static int l2_by_name(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(l2_names); i++) {
+ if (l2_names[i] == NULL)
+ continue;
+ if (!strcasecmp(name, l2_names[i]))
+ return i;
+ }
+ return -1;
+}
+
+static void help(void)
+{
+ printf( " -s --scan\n"
+ " -p --protocol {tcl,mifare-ultralight,mifare-classic}\n"
+ " -l --layer2 {iso14443a,iso14443b,iso15693}\n"
+ " -h --help\n");
+}
+
+static struct option opts[] = {
+ { "help", 0, 0, 'h' },
+ { "layer2", 1, 0, 'l' },
+ { "protocol", 1, 0, 'p' },
+ {0, 0, 0, 0}
+};
int main(int argc, char **argv)
{
int rc;
char buf[0x40];
- int i, protocol;
+ int i, protocol = -1, layer2 = -1;
+
+ printf("librfid_tool - (C) 2006 by Harald Welte\n"
+ "This program is Free Software and has "
+ "ABSOLUTELY NO WARRANTY\n\n");
-#if 0
- if (argc) {
- argc--;
- argv++;
- }
-
- while (argc) {
- if ( !strcmp (*argv, "--list")) {
- char *p;
- p = ccid_get_reader_list ();
- if (!p)
- return 1;
- fputs (p, stderr);
- free (p);
- return 0;
- }
- else if ( !strcmp (*argv, "--debug")) {
- ccid_set_debug_level (ccid_set_debug_level (-1) + 1);
- argc--; argv++;
- }
- else
- break;
- }
-#endif
+ printf("initializing librfid\n");
+ rfid_init();
- if (init() < 0)
- exit(1);
+ while (1) {
+ int c, option_index = 0;
+ c = getopt_long(argc, argv, "hp:l:s", opts, &option_index);
+ if (c == -1)
+ break;
- //while(1) { }
+ switch (c) {
+ case 's':
+ if (reader() < 0)
+ exit(1);
+ printf("scanning for RFID token...\n");
+ i = rfid_scan(rh, &l2h, &ph);
+ exit(0);
+ break;
+ case 'p':
+ protocol = proto_by_name(optarg);
+ if (protocol < 0) {
+ fprintf(stderr, "unknown protocol `%s'\n",
+ optarg);
+ exit(2);
+ }
+ break;
+ case 'l':
+ layer2 = l2_by_name(optarg);
+ if (layer2 < 0) {
+ fprintf(stderr, "unknown layer2 `%s'\n",
+ optarg);
+ exit(2);
+ }
+ break;
+ case 'h':
+ help();
+ exit(0);
+ break;
+ }
+ }
- //protocol = RFID_PROTOCOL_MIFARE_UL;
- //protocol = RFID_PROTOCOL_MIFARE_CLASSIC;
- protocol = RFID_PROTOCOL_TCL;
+ switch (protocol) {
+ case RFID_PROTOCOL_MIFARE_UL:
+ case RFID_PROTOCOL_MIFARE_CLASSIC:
+ layer2 = RFID_LAYER2_ISO14443A;
+ break;
+ case -1:
+ fprintf(stderr, "you have to specify --protocol\n");
+ exit(2);
+ }
+
+ if (layer2 < 0) {
+ fprintf(stderr, "you have to specify --layer2\n");
+ exit(2);
+ }
+
+ if (reader() < 0)
+ exit(1);
+
+ if (init(layer2) < 0)
+ exit(1);
if (l3(protocol) < 0)
exit(1);
int len = 200;
case RFID_PROTOCOL_TCL:
+ printf("Protocol T=CL\n");
/* we've established T=CL at this point */
- select_mf();
+ printf("selecting Master File\n");
+ rc = select_mf();
+ if (rc < 0) {
+ printf("error selecting MF\n");
+ break;
+ }
- iso7816_select_application();
- iso7816_select_ef(0x011e);
- iso7816_select_ef(0x0101);
+ printf("Getting random challenge, length 255\n");
+ rc = iso7816_get_challenge(0xff);
+ if (rc < 0) {
+ printf("error getting random challenge\n");
+ break;
+ }
+
+ printf("selecting Passport application\n");
+ rc = iso7816_select_application();
+ if (rc < 0) {
+ printf("error selecting passport application\n");
+ break;
+ }
+
+ printf("selecting EF 0x1e\n");
+ rc = iso7816_select_ef(0x011e);
+ if (rc < 0) {
+ printf("error selecting EF 0x1e\n");
+ break;
+ }
+
+ printf("selecting EF 0x01\n");
+ rc = iso7816_select_ef(0x0101);
+ if (rc < 0) {
+ printf("error selecting EF 0x01\n");
+ break;
+ }
while (1) {
+ printf("reading EF1\n");
len = 200;
printf("reading ef\n");
- iso7816_read_binary(buf, &len);
+ rc = iso7816_read_binary(buf, &len);
+ if (rc < 0) {
+ printf("error reading EF\n");
+ break;
+ }
}
#if 0
for (i = 0; i < 4; i++)
#endif
break;
case RFID_PROTOCOL_MIFARE_UL:
+ printf("Protocol Mifare Ultralight\n");
mifare_ulight_read(ph);
#if 0
mifare_ulight_blank(ph);
#endif
break;
case RFID_PROTOCOL_MIFARE_CLASSIC:
+ printf("Protocol Mifare Classic\n");
{
int sector;
for (sector = 1; sector < 31; sector++) {
printf("key format error\n");
exit(1);
}
- rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, sector);
+ rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, sector*4);
if (rc < 0) {
printf("mifare auth error\n");
exit(1);
}
}
break;
+ default:
+ printf("unknown protocol\n");
+ exit(1);
+ break;
}
rfid_reader_close(rh);