diff options
Diffstat (limited to 'easytool/easytool.c')
| -rw-r--r-- | easytool/easytool.c | 83 | 
1 files changed, 33 insertions, 50 deletions
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;  | 
