選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

mfcuk_finger.c 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. LICENSE
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /*
  15. Package:
  16. MiFare Classic Universal toolKit (MFCUK)
  17. Package version:
  18. 0.1
  19. Filename:
  20. mfcuk_finger.c
  21. Description:
  22. MFCUK fingerprinting and specific data-decoding functionality.
  23. License:
  24. GPL2, Copyright (C) 2009, Andrei Costin
  25. * @file mfcuk_finger.c
  26. * @brief MFCUK fingerprinting and specific data-decoding functionality.
  27. * @todo add proper error codes
  28. */
  29. #include "mfcuk_finger.h"
  30. mfcuk_finger_tmpl_entry mfcuk_finger_db[] = {
  31. { "./data/tmpls_fingerprints/mfcuk_tmpl_skgt.mfd", "Sofia SKGT", mfcuk_finger_default_comparator, mfcuk_finger_skgt_decoder, NULL },
  32. { "./data/tmpls_fingerprints/mfcuk_tmpl_ratb.mfd", "Bucharest RATB", mfcuk_finger_default_comparator, mfcuk_finger_default_decoder, NULL },
  33. { "./data/tmpls_fingerprints/mfcuk_tmpl_oyster.mfd", "London OYSTER", mfcuk_finger_default_comparator, mfcuk_finger_default_decoder, NULL },
  34. };
  35. int mfcuk_finger_db_entries = sizeof(mfcuk_finger_db) / sizeof(mfcuk_finger_db[0]);
  36. int mfcuk_finger_default_decoder(mifare_classic_tag *dump)
  37. {
  38. if (!dump) {
  39. fprintf(stderr, "ERROR: cannot decode a NULL pointer :)\n");
  40. return 0;
  41. }
  42. printf("UID:\t%02x%02x%02x%02x\n", dump->amb[0].mbm.abtUID[0], dump->amb[0].mbm.abtUID[1], dump->amb[0].mbm.abtUID[2], dump->amb[0].mbm.abtUID[3]);
  43. printf("TYPE:\t%02x\n", dump->amb[0].mbm.btUnknown);
  44. return 1;
  45. }
  46. // Yes, I know C++ class inheritance would perfectly fit the decoders/comparators... Though C is more to my heart. Anyone to rewrite in C++?
  47. int mfcuk_finger_skgt_decoder(mifare_classic_tag *dump)
  48. {
  49. if (!dump) {
  50. fprintf(stderr, "ERROR: cannot decode a NULL pointer :)\n");
  51. return 0;
  52. }
  53. printf("Bulgaria/Sofia/SKGT public transport card information decoder (info credits to Andy)\n");
  54. mfcuk_finger_default_decoder(dump);
  55. printf("LAST TRAVEL DATA\n");
  56. // TODO: get proper information
  57. return 1;
  58. }
  59. int mfcuk_finger_default_comparator(mifare_classic_tag *dump, mfcuk_finger_template *tmpl, float *score)
  60. {
  61. int max_bytes = 0;
  62. int i;
  63. int num_bytes_tomatch = 0;
  64. int num_bytes_matched = 0;
  65. if ((!dump) || (!tmpl) || (!score)) {
  66. return 0;
  67. }
  68. if (IS_MIFARE_CLASSIC_1K_TAG(dump)) {
  69. max_bytes = MIFARE_CLASSIC_BYTES_PER_BLOCK * MIFARE_CLASSIC_1K_MAX_BLOCKS;
  70. } else if (IS_MIFARE_CLASSIC_4K_TAG(dump)) {
  71. max_bytes = MIFARE_CLASSIC_BYTES_PER_BLOCK * MIFARE_CLASSIC_4K_MAX_BLOCKS;
  72. } else {
  73. return 0;
  74. }
  75. for (i = 0; i < max_bytes; i++) {
  76. if (((char *)(&tmpl->mask))[i] == 0x0) {
  77. continue;
  78. }
  79. num_bytes_tomatch++;
  80. if (((char *)(&tmpl->values))[i] == ((char *)dump)[i]) {
  81. num_bytes_matched++;
  82. }
  83. }
  84. if (num_bytes_tomatch == 0) {
  85. return 0;
  86. } else {
  87. *score = (float)(num_bytes_matched) / num_bytes_tomatch;
  88. }
  89. return 1;
  90. }
  91. int mfcuk_finger_load(void)
  92. {
  93. int i;
  94. mifare_classic_tag mask;
  95. mifare_classic_tag values;
  96. FILE *fp = NULL;
  97. size_t result = 0;
  98. mfcuk_finger_template *tmpl_new = NULL;
  99. int template_loaded_count = 0;
  100. for (i = 0; i < mfcuk_finger_db_entries; i++) {
  101. fp = fopen(mfcuk_finger_db[i].tmpl_filename, "rb");
  102. if (!fp) {
  103. fprintf(stderr, "WARN: cannot open template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
  104. continue;
  105. }
  106. // If not read exactly 1 record, something is wrong
  107. if ((result = fread((void *)(&mask), sizeof(mask), 1, fp)) != 1) {
  108. fprintf(stderr, "WARN: cannot read MASK from template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
  109. fclose(fp);
  110. continue;
  111. }
  112. // If not read exactly 1 record, something is wrong
  113. if ((result = fread((void *)(&values), sizeof(values), 1, fp)) != 1) {
  114. fprintf(stderr, "WARN: cannot read VALUES template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
  115. fclose(fp);
  116. continue;
  117. }
  118. if (mfcuk_finger_db[i].tmpl_data == NULL) {
  119. if ((tmpl_new = (mfcuk_finger_template *) malloc(sizeof(mfcuk_finger_template))) == NULL) {
  120. fprintf(stderr, "WARN: cannot allocate memory to template record %d\n", i);
  121. fclose(fp);
  122. continue;
  123. }
  124. memcpy(&(tmpl_new->mask), &(mask), sizeof(mask));
  125. memcpy(&(tmpl_new->values), &(values), sizeof(values));
  126. mfcuk_finger_db[i].tmpl_data = tmpl_new;
  127. template_loaded_count++;
  128. }
  129. if (fp) {
  130. fclose(fp);
  131. fp = NULL;
  132. }
  133. }
  134. return template_loaded_count;
  135. }
  136. int mfcuk_finger_unload(void)
  137. {
  138. int i;
  139. for (i = 0; i < mfcuk_finger_db_entries; i++) {
  140. if (mfcuk_finger_db[i].tmpl_data != NULL) {
  141. free(mfcuk_finger_db[i].tmpl_data);
  142. mfcuk_finger_db[i].tmpl_data = NULL;
  143. }
  144. }
  145. return 1;
  146. }