summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--easytool/Makefile2
-rw-r--r--easytool/easytool.c83
-rw-r--r--easytool/mifare_classic.c29
-rw-r--r--easytool/mifare_classic.h16
4 files changed, 79 insertions, 51 deletions
diff --git a/easytool/Makefile b/easytool/Makefile
index fc5a5e1..81b3ae2 100644
--- a/easytool/Makefile
+++ b/easytool/Makefile
@@ -6,7 +6,7 @@ all: easytool
clean:
@rm -f *.o easytool
-easytool: easytool.o data.o utils.o
+easytool: easytool.o data.o utils.o mifare_classic.o
$(CC) $(LDFLAGS) -o $@ $^
%.o: %.c
diff --git a/easytool/easytool.c b/easytool/easytool.c
index b02842d..f8da4e0 100644
--- a/easytool/easytool.c
+++ b/easytool/easytool.c
@@ -19,8 +19,7 @@
*
*/
-
-
+/* System includes */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -31,12 +30,15 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
-
#include <netinet/in.h>
+/* libnfc includes */
#include <nfc/nfc-types.h>
#include <nfc/mifaretag.h>
+#include "mifare_classic.h"
+
+/* Easycard specific includes */
#include "easycard.h"
struct {
@@ -45,50 +47,7 @@ struct {
mifare_tag *mft;
} global;
-#define ABP_C1 0x04
-#define ABP_C2 0x02
-#define ABP_C3 0x01
-
-struct acc_bits_parsed {
- uint8_t block[4];
-};
-
-static void dump_acc_bits(const struct acc_bits_parsed *abp)
-{
- uint8_t block;
-
- for (block = 0; block < 4; block++) {
- printf("\tBlock %u: %x (%u %u %u)\n", block, abp->block[block],
- abp->block[block] & ABP_C1 ? 1 : 0,
- abp->block[block] & ABP_C2 ? 1 : 0,
- abp->block[block] & ABP_C3 ? 1 : 0);
- }
-}
-
-static void parse_acc_bits(struct acc_bits_parsed *abp, uint8_t *acc_bits)
-{
- uint8_t c1, c2, c3;
- uint8_t block;
-
- memset(abp, 0, sizeof(*abp));
-
- c1 = acc_bits[1] >> 4;
- c2 = acc_bits[2] & 0xf;
- c3 = acc_bits[2] >> 4;
-
- printf("C1 = %x, C2 = %x, C3 = %x\n", c1, c2, c3);
-
- for (block = 0; block < 4; block++) {
- uint8_t testbit = 1 << block;
- if (c1 & testbit)
- abp->block[block] |= ABP_C1;
- if (c2 & testbit)
- abp->block[block] |= ABP_C2;
- if (c3 & testbit)
- abp->block[block] |= ABP_C3;
- }
-}
-
+/* Sector 0 of Block 2 seems to contain manufacturing timestamp */
struct easy_block2sec0 {
uint8_t unknown[6];
uint8_t timestamp[3];
@@ -109,6 +68,14 @@ struct easy_log_rec {
uint8_t unknown3[2];
} __attribute__ ((packed));
+/* Mifare classic VALUE BLOCK */
+struct mfcl_value_block {
+ uint32_t value; /* value in NTD */
+ uint32_t value_inv; /* bit-inverted copy of value in NTD */
+ uint32_t value_backup; /* backup copy of value in NTD */
+ uint8_t addr[4];
+} __attribute__ ((packed));
+
static time_t easy_timestamp2time(const uint8_t *easy_ts)
{
return (easy_ts[2] << 16 | easy_ts[1] << 8 | easy_ts[0]) << 8;
@@ -144,6 +111,18 @@ static void dump_easy_log(const struct easy_log_rec *elr)
}
}
+static void dump_acc_bits(const struct acc_bits_parsed *abp)
+{
+ uint8_t block;
+
+ for (block = 0; block < 4; block++) {
+ printf("\tBlock %u: %x (%u %u %u)\n", block, abp->block[block],
+ abp->block[block] & ABP_C1 ? 1 : 0,
+ abp->block[block] & ABP_C2 ? 1 : 0,
+ abp->block[block] & ABP_C3 ? 1 : 0);
+ }
+}
+
static void dump_mfcl(mifare_tag *mft)
{
unsigned int sect;
@@ -160,7 +139,7 @@ static void dump_mfcl(mifare_tag *mft)
printf("Sector %02u (base: 0x%02x) Access bits: 0x%08x\n", sect,
sect*4*16, ntohl(*((uint32_t *) access_bits)));
- parse_acc_bits(&abp, access_bits);
+ mfcl_parse_acc_bits(&abp, access_bits);
dump_acc_bits(&abp);
}
}
@@ -169,18 +148,22 @@ static void dump_easycard(mifare_tag *mft)
{
unsigned int sect;
mifare_block_manufacturer *manuf = &mft->amb[0].mbm;
- struct easy_block2sec0 *b2s0 = mft->amb[4].mbd.abtData;
+ struct mfcl_value_block *val =
+ (struct mfcl_value_block *) mft->amb[8].mbd.abtData;
+ struct easy_block2sec0 *b2s0 =
+ (struct easy_block2sec0 *) mft->amb[4].mbd.abtData;
uint32_t uid = ntohl(*((uint32_t *) manuf->abtUID));
/* dump the header */
printf("EasyCard UID 0x%08x (%u)\n", uid, uid);
printf("Date of manufacture: %s\n",
easy_asc_timestamp(b2s0->timestamp));
+ printf("Current Balance: %5u NTD\n", val->value);
+ printf("\nTransaction Log:\n");
/* dump the transaction log */
for (sect = 3; sect <=4; sect++) {
unsigned int block_base = sect * 4;
- uint8_t *access_bits = mft->amb[block_base+3].mbt.abtAccessBits;
unsigned int i;
for (i = 0; i < 3; i++) {
void *data = mft->amb[block_base+i].mbd.abtData;
diff --git a/easytool/mifare_classic.c b/easytool/mifare_classic.c
new file mode 100644
index 0000000..e516631
--- /dev/null
+++ b/easytool/mifare_classic.c
@@ -0,0 +1,29 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "mifare_classic.h"
+
+void mfcl_parse_acc_bits(struct acc_bits_parsed *abp, uint8_t *acc_bits)
+{
+ uint8_t c1, c2, c3;
+ uint8_t block;
+
+ memset(abp, 0, sizeof(*abp));
+
+ c1 = acc_bits[1] >> 4;
+ c2 = acc_bits[2] & 0xf;
+ c3 = acc_bits[2] >> 4;
+
+ printf("C1 = %x, C2 = %x, C3 = %x\n", c1, c2, c3);
+
+ for (block = 0; block < 4; block++) {
+ uint8_t testbit = 1 << block;
+ if (c1 & testbit)
+ abp->block[block] |= ABP_C1;
+ if (c2 & testbit)
+ abp->block[block] |= ABP_C2;
+ if (c3 & testbit)
+ abp->block[block] |= ABP_C3;
+ }
+}
diff --git a/easytool/mifare_classic.h b/easytool/mifare_classic.h
new file mode 100644
index 0000000..c6ba524
--- /dev/null
+++ b/easytool/mifare_classic.h
@@ -0,0 +1,16 @@
+#ifndef EASY_MFCL_H
+#define EASY_MFCL_H
+
+#include <stdint.h>
+
+#define ABP_C1 0x04
+#define ABP_C2 0x02
+#define ABP_C3 0x01
+
+struct acc_bits_parsed {
+ uint8_t block[4];
+};
+
+void mfcl_parse_acc_bits(struct acc_bits_parsed *abp, uint8_t *acc_bits);
+
+#endif
personal git repositories of Harald Welte. Your mileage may vary