libnfc 1.3.9
|
00001 /*- 00002 * Public platform independent Near Field Communication (NFC) library 00003 * 00004 * Copyright (C) 2009, Roel Verdult 00005 * 00006 * This program is free software: you can redistribute it and/or modify it 00007 * under the terms of the GNU Lesser General Public License as published by the 00008 * Free Software Foundation, either version 3 of the License, or (at your 00009 * option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, but WITHOUT 00012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00014 * more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 00018 */ 00019 00025 #ifdef HAVE_CONFIG_H 00026 # include "config.h" 00027 #endif // HAVE_CONFIG_H 00028 00029 #include <stdio.h> 00030 #include <stdlib.h> 00031 #include <stddef.h> 00032 #include <stdint.h> 00033 #include <string.h> 00034 00035 #include <nfc/nfc.h> 00036 00037 #include <nfc/nfc-messages.h> 00038 #include "nfc-utils.h" 00039 00040 #define MAX_FRAME_LEN 264 00041 00042 static byte_t abtRecv[MAX_FRAME_LEN]; 00043 static size_t szRecvBits; 00044 static nfc_device_t *pnd; 00045 00046 // ISO14443A Anti-Collision response 00047 byte_t abtAtqa[2] = { 0x04, 0x00 }; 00048 byte_t abtUidBcc[5] = { 0xDE, 0xAD, 0xBE, 0xAF, 0x62 }; 00049 byte_t abtSak[9] = { 0x08, 0xb6, 0xdd }; 00050 00051 void 00052 print_usage (char *argv[]) 00053 { 00054 printf ("Usage: %s [OPTIONS] [UID]\n", argv[0]); 00055 printf ("Options:\n"); 00056 printf ("\t-h\tHelp. Print this message.\n"); 00057 printf ("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n"); 00058 printf ("\n"); 00059 printf ("\t[UID]\tUID to emulate, specified as 8 HEX digits (default is DEADBEAF).\n"); 00060 } 00061 00062 int 00063 main (int argc, char *argv[]) 00064 { 00065 byte_t *pbtTx = NULL; 00066 size_t szTxBits; 00067 bool quiet_output = false; 00068 00069 int arg, 00070 i; 00071 00072 // Get commandline options 00073 for (arg = 1; arg < argc; arg++) { 00074 if (0 == strcmp (argv[arg], "-h")) { 00075 print_usage (argv); 00076 return 0; 00077 } else if (0 == strcmp (argv[arg], "-q")) { 00078 INFO ("%s", "Quiet mode."); 00079 quiet_output = true; 00080 } else if ((arg == argc - 1) && (strlen (argv[arg]) == 8)) { // See if UID was specified as HEX string 00081 byte_t abtTmp[3] = { 0x00, 0x00, 0x00 }; 00082 printf ("[+] Using UID: %s\n", argv[arg]); 00083 abtUidBcc[4] = 0x00; 00084 for (i = 0; i < 4; ++i) { 00085 memcpy (abtTmp, argv[arg] + i * 2, 2); 00086 abtUidBcc[i] = (byte_t) strtol ((char *) abtTmp, NULL, 16); 00087 abtUidBcc[4] ^= abtUidBcc[i]; 00088 } 00089 } else { 00090 ERR ("%s is not supported option.", argv[arg]); 00091 print_usage (argv); 00092 return -1; 00093 } 00094 } 00095 00096 // Try to open the NFC reader 00097 pnd = nfc_connect (NULL); 00098 00099 if (pnd == NULL) { 00100 printf ("Error connecting NFC reader\n"); 00101 return 1; 00102 } 00103 00104 printf ("\n"); 00105 printf ("[+] Connected to NFC reader: %s\n", pnd->acName); 00106 printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n"); 00107 printf ("[+] To do this, please send any command after the anti-collision\n"); 00108 printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n"); 00109 if (!nfc_target_init (pnd, abtRecv, &szRecvBits)) { 00110 printf ("Error: Could not come out of auto-emulation, no command was received\n"); 00111 return 1; 00112 } 00113 printf ("[+] Received initiator command: "); 00114 print_hex_bits (abtRecv, szRecvBits); 00115 printf ("[+] Configuring communication\n"); 00116 if (!nfc_configure (pnd, NDO_HANDLE_CRC, false) || !nfc_configure (pnd, NDO_HANDLE_PARITY, true)) { 00117 nfc_perror (pnd, "nfc_configure"); 00118 exit (EXIT_FAILURE); 00119 } 00120 printf ("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n", abtUidBcc[0], abtUidBcc[1], 00121 abtUidBcc[2], abtUidBcc[3]); 00122 00123 while (true) { 00124 // Test if we received a frame 00125 if (nfc_target_receive_bits (pnd, abtRecv, &szRecvBits, NULL)) { 00126 // Prepare the command to send back for the anti-collision request 00127 switch (szRecvBits) { 00128 case 7: // Request or Wakeup 00129 pbtTx = abtAtqa; 00130 szTxBits = 16; 00131 // New anti-collsion session started 00132 if (!quiet_output) 00133 printf ("\n"); 00134 break; 00135 00136 case 16: // Select All 00137 pbtTx = abtUidBcc; 00138 szTxBits = 40; 00139 break; 00140 00141 case 72: // Select Tag 00142 pbtTx = abtSak; 00143 szTxBits = 24; 00144 break; 00145 00146 default: // unknown length? 00147 szTxBits = 0; 00148 break; 00149 } 00150 00151 if (!quiet_output) { 00152 printf ("R: "); 00153 print_hex_bits (abtRecv, szRecvBits); 00154 } 00155 // Test if we know how to respond 00156 if (szTxBits) { 00157 // Send and print the command to the screen 00158 if (!nfc_target_send_bits (pnd, pbtTx, szTxBits, NULL)) { 00159 nfc_perror (pnd, "nfc_target_send_bits"); 00160 exit (EXIT_FAILURE); 00161 } 00162 if (!quiet_output) { 00163 printf ("T: "); 00164 print_hex_bits (pbtTx, szTxBits); 00165 } 00166 } 00167 } 00168 } 00169 00170 nfc_disconnect (pnd); 00171 exit (EXIT_SUCCESS); 00172 }