61 # define SUSP_TIME 1 // secs.
64 # include "../contrib/windows.h"
67 # define SUSP_TIME 1000 // msecs.
70 #define MAX_FRAME_LEN 264
71 #define MAX_DEVICE_COUNT 2
73 static byte_t abtCapdu[MAX_FRAME_LEN];
74 static size_t szCapduLen;
75 static byte_t abtRapdu[MAX_FRAME_LEN];
76 static size_t szRapduLen;
79 static bool quitting =
false;
80 static bool quiet_output =
false;
81 static bool initiator_only_mode =
false;
82 static bool target_only_mode =
false;
83 static int waiting_time = 0;
90 printf (
"\nQuitting...\n");
91 printf (
"Please send a last command to the emulator to quit properly.\n");
97 print_usage (
char *argv[])
99 printf (
"Usage: %s [OPTIONS]\n", argv[0]);
100 printf (
"Options:\n");
101 printf (
"\t-h\tHelp. Print this message.\n");
102 printf (
"\t-q\tQuiet mode. Suppress printing of relayed data (improves timing).\n");
103 printf (
"\t-t\tTarget mode only (the one on reader side). Data expected from FD3 to FD4.\n");
104 printf (
"\t-i\tInitiator mode only (the one on tag side). Data expected from FD3 to FD4.\n");
105 printf (
"\t-n N\tAdds a waiting time of N seconds (integer) in the relay to mimic long distance.\n");
108 bool print_hex_fd4 (
const byte_t * pbtData,
const size_t szBytes,
const char * pchPrefix)
111 if (szBytes > MAX_FRAME_LEN) {
114 if (fprintf (fd4,
"#%s %04zx: ", pchPrefix, szBytes)<0) {
118 for (szPos = 0; szPos < szBytes; szPos++) {
119 if (fprintf (fd4,
"%02x ", pbtData[szPos])<0) {
123 if (fprintf (fd4,
"\n")<0) {
130 bool scan_hex_fd3 (byte_t *pbtData,
size_t *pszBytes,
const char * pchPrefix)
133 unsigned int uiBytes;
138 while ( (c=fgetc(fd3)) !=
'#') {
143 strncpy(pchScan, pchPrefix, 250);
144 strcat(pchScan,
" %04x:");
145 if (fscanf (fd3, pchScan, &uiBytes)<1) {
149 if (*pszBytes > MAX_FRAME_LEN) {
152 for (szPos = 0; szPos < *pszBytes; szPos++) {
153 if (fscanf (fd3,
"%02x", &uiData)<1) {
156 pbtData[szPos]=uiData;
162 main (
int argc,
char *argv[])
171 for (arg = 1; arg < argc; arg++) {
172 if (0 == strcmp (argv[arg],
"-h")) {
175 }
else if (0 == strcmp (argv[arg],
"-q")) {
177 }
else if (0 == strcmp (argv[arg],
"-t")) {
178 printf (
"INFO: %s\n",
"Target mode only.");
179 initiator_only_mode =
false;
180 target_only_mode =
true;
181 }
else if (0 == strcmp (argv[arg],
"-i")) {
182 printf (
"INFO: %s\n",
"Initiator mode only.");
183 initiator_only_mode =
true;
184 target_only_mode =
false;
185 }
else if (0 == strcmp (argv[arg],
"-n")) {
186 if (++arg==argc || (sscanf(argv[arg],
"%i", &waiting_time)<1)) {
187 ERR (
"Missing or wrong waiting time value: %s.", argv[arg]);
191 printf (
"Waiting time: %i secs.\n", waiting_time);
193 ERR (
"%s is not supported option.", argv[arg]);
200 printf (
"%s use libnfc %s\n", argv[0], acLibnfcVersion);
203 signal (SIGINT, (
void (__cdecl *) (
int)) intr_hdlr);
205 signal (SIGINT, (
void (*)()) intr_hdlr);
209 if (!(pnddDevices = malloc (MAX_DEVICE_COUNT *
sizeof (*pnddDevices)))) {
210 fprintf (stderr,
"malloc() failed\n");
216 if (initiator_only_mode || target_only_mode) {
218 ERR (
"No device found");
221 fd3 = fdopen(3,
"r");
222 fd4 = fdopen(4,
"w");
226 ERR (
"%zd device found but two connected devices are needed to relay NFC.", szFound);
231 if (!target_only_mode) {
244 printf (
"Error connecting NFC reader\n");
248 printf (
"Connected to the NFC reader device: %s\n", pndInitiator->
acName);
252 .nmt = NMT_ISO14443A,
256 printf (
"Error: no tag was found\n");
261 printf(
"Found tag:\n");
262 print_nfc_iso14443a_info (ntRealTarget.nti.nai,
false);
263 if (initiator_only_mode) {
264 if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen,
"UID") != EXIT_SUCCESS) {
265 fprintf (stderr,
"Error while printing UID to FD4\n");
269 if (print_hex_fd4(ntRealTarget.nti.nai.abtAtqa, 2,
"ATQA") != EXIT_SUCCESS) {
270 fprintf (stderr,
"Error while printing ATQA to FD4\n");
274 if (print_hex_fd4(&(ntRealTarget.nti.nai.btSak), 1,
"SAK") != EXIT_SUCCESS) {
275 fprintf (stderr,
"Error while printing SAK to FD4\n");
279 if (print_hex_fd4(ntRealTarget.nti.nai.abtAts, ntRealTarget.nti.nai.szAtsLen,
"ATS") != EXIT_SUCCESS) {
280 fprintf (stderr,
"Error while printing ATS to FD4\n");
286 if (initiator_only_mode) {
287 printf (
"Hint: tag <---> *INITIATOR* (relay) <-FD3/FD4-> target (relay) <---> original reader\n\n");
288 }
else if (target_only_mode) {
289 printf (
"Hint: tag <---> initiator (relay) <-FD3/FD4-> *TARGET* (relay) <---> original reader\n\n");
291 printf (
"Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n");
293 if (!initiator_only_mode) {
295 .nm.nmt = NMT_ISO14443A,
298 if (target_only_mode) {
300 if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtUid, &(ntEmulatedTarget.nti.nai.szUidLen),
"UID") != EXIT_SUCCESS) {
301 fprintf (stderr,
"Error while scanning UID from FD3\n");
305 if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAtqa, &foo,
"ATQA") != EXIT_SUCCESS) {
306 fprintf (stderr,
"Error while scanning ATQA from FD3\n");
310 if (scan_hex_fd3(&(ntEmulatedTarget.nti.nai.btSak), &foo,
"SAK") != EXIT_SUCCESS) {
311 fprintf (stderr,
"Error while scanning SAK from FD3\n");
315 if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAts, &(ntEmulatedTarget.nti.nai.szAtsLen),
"ATS") != EXIT_SUCCESS) {
316 fprintf (stderr,
"Error while scanning ATS from FD3\n");
321 ntEmulatedTarget.nti = ntRealTarget.nti;
324 ntEmulatedTarget.nti.nai.szUidLen = 4;
325 ntEmulatedTarget.nti.nai.abtAtqa[1] &= (0xFF-0x40);
327 ntEmulatedTarget.nti.nai.abtUid[0] = 0x08;
341 pbtTk = iso14443a_locate_historical_bytes (ntEmulatedTarget.nti.nai.abtAts, ntEmulatedTarget.nti.nai.szAtsLen, &szTk);
342 szTk = (szTk > 48) ? 48 : szTk;
344 memcpy(pbtTkt, pbtTk, szTk);
345 ntEmulatedTarget.nti.nai.abtAts[0] = 0x75;
346 ntEmulatedTarget.nti.nai.abtAts[1] = 0x33;
347 ntEmulatedTarget.nti.nai.abtAts[2] = 0x92;
348 ntEmulatedTarget.nti.nai.abtAts[3] = 0x03;
349 ntEmulatedTarget.nti.nai.szAtsLen = 4 + szTk;
350 memcpy(&(ntEmulatedTarget.nti.nai.abtAts[4]), pbtTkt, szTk);
352 printf(
"We will emulate:\n");
353 print_nfc_iso14443a_info (ntEmulatedTarget.nti.nai,
false);
357 if (pndTarget == NULL) {
358 printf (
"Error connecting NFC emulator device\n");
359 if (!target_only_mode) {
365 printf (
"Connected to the NFC emulator device: %s\n", pndTarget->
acName);
367 if (!
nfc_target_init (pndTarget, &ntEmulatedTarget, abtCapdu, &szCapduLen)) {
368 ERR (
"%s",
"Initialization of NFC emulator failed");
369 if (!target_only_mode) {
375 printf (
"%s\n",
"Done, relaying frames now!");
381 if (!initiator_only_mode) {
384 nfc_perror (pndTarget,
"nfc_target_receive_bytes");
385 if (!target_only_mode) {
391 if (target_only_mode) {
392 if (print_hex_fd4(abtCapdu, szCapduLen,
"C-APDU") != EXIT_SUCCESS) {
393 fprintf (stderr,
"Error while printing C-APDU to FD4\n");
399 if (scan_hex_fd3(abtCapdu, &szCapduLen,
"C-APDU") != EXIT_SUCCESS) {
400 fprintf (stderr,
"Error while scanning C-APDU from FD3\n");
407 printf (
"Forwarding C-APDU: ");
408 print_hex (abtCapdu, szCapduLen);
411 if (!target_only_mode) {
414 (pndInitiator, abtCapdu, szCapduLen, abtRapdu, &szRapduLen);
416 if (scan_hex_fd3(abtRapdu, &szRapduLen,
"R-APDU") != EXIT_SUCCESS) {
417 fprintf (stderr,
"Error while scanning R-APDU from FD3\n");
425 if (waiting_time > 0) {
427 printf (
"Waiting %is to simulate longer relay...\n", waiting_time);
429 sleep(waiting_time * SUSP_TIME);
433 printf (
"Forwarding R-APDU: ");
434 print_hex (abtRapdu, szRapduLen);
436 if (!initiator_only_mode) {
439 nfc_perror (pndTarget,
"nfc_target_send_bytes");
440 if (!target_only_mode) {
443 if (!initiator_only_mode) {
449 if (print_hex_fd4(abtRapdu, szRapduLen,
"R-APDU") != EXIT_SUCCESS) {
450 fprintf (stderr,
"Error while printing R-APDU to FD4\n");
458 if (!target_only_mode) {
461 if (!initiator_only_mode) {