64 #define MAX_FRAME_LEN 264
65 #define MAX_DEVICE_COUNT 2
67 static uint8_t abtCapdu[MAX_FRAME_LEN];
68 static size_t szCapduLen;
69 static uint8_t abtRapdu[MAX_FRAME_LEN];
70 static size_t szRapduLen;
73 static bool quitting =
false;
74 static bool quiet_output =
false;
75 static bool initiator_only_mode =
false;
76 static bool target_only_mode =
false;
77 static bool swap_devices =
false;
78 static int waiting_time = 0;
86 printf(
"\nQuitting...\n");
87 printf(
"Please send a last command to the emulator to quit properly.\n");
93 print_usage(
char *argv[])
95 printf(
"Usage: %s [OPTIONS]\n", argv[0]);
97 printf(
"\t-h\tHelp. Print this message.\n");
98 printf(
"\t-q\tQuiet mode. Suppress printing of relayed data (improves timing).\n");
99 printf(
"\t-t\tTarget mode only (the one on reader side). Data expected from FD3 to FD4.\n");
100 printf(
"\t-i\tInitiator mode only (the one on tag side). Data expected from FD3 to FD4.\n");
101 printf(
"\t-n N\tAdds a waiting time of N seconds (integer) in the relay to mimic long distance.\n");
104 static int print_hex_fd4(
const uint8_t *pbtData,
const size_t szBytes,
const char *pchPrefix)
107 if (szBytes > MAX_FRAME_LEN) {
110 if (fprintf(fd4,
"#%s %04" PRIxPTR
": ", pchPrefix, szBytes) < 0) {
114 for (szPos = 0; szPos < szBytes; szPos++) {
115 if (fprintf(fd4,
"%02x ", pbtData[szPos]) < 0) {
119 if (fprintf(fd4,
"\n") < 0) {
126 static int scan_hex_fd3(uint8_t *pbtData,
size_t *pszBytes,
const char *pchPrefix)
129 unsigned int uiBytes;
134 while ((c = fgetc(fd3)) !=
'#') {
139 strncpy(pchScan, pchPrefix, 250);
140 pchScan[
sizeof(pchScan) - 1] =
'\0';
141 strcat(pchScan,
" %04x:");
142 if (fscanf(fd3, pchScan, &uiBytes) < 1) {
146 if (*pszBytes > MAX_FRAME_LEN) {
149 for (szPos = 0; szPos < *pszBytes; szPos++) {
150 if (fscanf(fd3,
"%02x", &uiData) < 1) {
153 pbtData[szPos] = uiData;
159 main(
int argc,
char *argv[])
166 for (arg = 1; arg < argc; arg++) {
167 if (0 == strcmp(argv[arg],
"-h")) {
170 }
else if (0 == strcmp(argv[arg],
"-q")) {
172 }
else if (0 == strcmp(argv[arg],
"-t")) {
173 printf(
"INFO: %s\n",
"Target mode only.");
174 initiator_only_mode =
false;
175 target_only_mode =
true;
176 }
else if (0 == strcmp(argv[arg],
"-i")) {
177 printf(
"INFO: %s\n",
"Initiator mode only.");
178 initiator_only_mode =
true;
179 target_only_mode =
false;
180 }
else if (0 == strcmp(argv[arg],
"-s")) {
181 printf(
"INFO: %s\n",
"Swapping devices.");
183 }
else if (0 == strcmp(argv[arg],
"-n")) {
184 if (++arg == argc || (sscanf(argv[arg],
"%10i", &waiting_time) < 1)) {
185 ERR(
"Missing or wrong waiting time value: %s.", argv[arg]);
189 printf(
"Waiting time: %i secs.\n", waiting_time);
191 ERR(
"%s is not supported option.", argv[arg]);
198 printf(
"%s uses libnfc %s\n", argv[0], acLibnfcVersion);
201 signal(SIGINT, (
void (__cdecl *)(
int)) intr_hdlr);
203 signal(SIGINT, intr_hdlr);
208 if (context == NULL) {
209 ERR(
"Unable to init libnfc (malloc)");
217 if (initiator_only_mode || target_only_mode) {
219 ERR(
"No device found");
223 if ((fd3 = fdopen(3,
"r")) == NULL) {
224 ERR(
"Could not open file descriptor 3");
228 if ((fd4 = fdopen(4,
"r")) == NULL) {
229 ERR(
"Could not open file descriptor 4");
235 ERR(
"%" PRIdPTR
" device found but two opened devices are needed to relay NFC.", szFound);
241 if (!target_only_mode) {
247 if ((szFound == 1) || swap_devices) {
248 pndInitiator =
nfc_open(context, connstrings[0]);
250 pndInitiator =
nfc_open(context, connstrings[1]);
253 if (pndInitiator == NULL) {
254 printf(
"Error opening NFC reader\n");
262 printf(
"Error: fail initializing initiator\n");
270 .nmt = NMT_ISO14443A,
274 printf(
"Error: no tag was found\n");
280 printf(
"Found tag:\n");
281 print_nfc_target(&ntRealTarget,
false);
282 if (initiator_only_mode) {
283 if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen,
"UID") < 0) {
284 fprintf(stderr,
"Error while printing UID to FD4\n");
289 if (print_hex_fd4(ntRealTarget.nti.nai.abtAtqa, 2,
"ATQA") < 0) {
290 fprintf(stderr,
"Error while printing ATQA to FD4\n");
295 if (print_hex_fd4(&(ntRealTarget.nti.nai.btSak), 1,
"SAK") < 0) {
296 fprintf(stderr,
"Error while printing SAK to FD4\n");
301 if (print_hex_fd4(ntRealTarget.nti.nai.abtAts, ntRealTarget.nti.nai.szAtsLen,
"ATS") < 0) {
302 fprintf(stderr,
"Error while printing ATS to FD4\n");
309 if (initiator_only_mode) {
310 printf(
"Hint: tag <---> *INITIATOR* (relay) <-FD3/FD4-> target (relay) <---> original reader\n\n");
311 }
else if (target_only_mode) {
312 printf(
"Hint: tag <---> initiator (relay) <-FD3/FD4-> *TARGET* (relay) <---> original reader\n\n");
314 printf(
"Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n");
316 if (!initiator_only_mode) {
319 .nmt = NMT_ISO14443A,
323 if (target_only_mode) {
325 if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtUid, &(ntEmulatedTarget.nti.nai.szUidLen),
"UID") < 0) {
326 fprintf(stderr,
"Error while scanning UID from FD3\n");
331 if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAtqa, &foo,
"ATQA") < 0) {
332 fprintf(stderr,
"Error while scanning ATQA from FD3\n");
337 if (scan_hex_fd3(&(ntEmulatedTarget.nti.nai.btSak), &foo,
"SAK") < 0) {
338 fprintf(stderr,
"Error while scanning SAK from FD3\n");
343 if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAts, &(ntEmulatedTarget.nti.nai.szAtsLen),
"ATS") < 0) {
344 fprintf(stderr,
"Error while scanning ATS from FD3\n");
350 ntEmulatedTarget.nti = ntRealTarget.nti;
353 ntEmulatedTarget.nti.nai.szUidLen = 4;
354 ntEmulatedTarget.nti.nai.abtAtqa[1] &= (0xFF - 0x40);
356 ntEmulatedTarget.nti.nai.abtUid[0] = 0x08;
370 pbtTk = iso14443a_locate_historical_bytes(ntEmulatedTarget.nti.nai.abtAts, ntEmulatedTarget.nti.nai.szAtsLen, &szTk);
371 szTk = (szTk > 48) ? 48 : szTk;
373 memcpy(pbtTkt, pbtTk, szTk);
374 ntEmulatedTarget.nti.nai.abtAts[0] = 0x75;
375 ntEmulatedTarget.nti.nai.abtAts[1] = 0x33;
376 ntEmulatedTarget.nti.nai.abtAts[2] = 0x92;
377 ntEmulatedTarget.nti.nai.abtAts[3] = 0x03;
378 ntEmulatedTarget.nti.nai.szAtsLen = 4 + szTk;
379 memcpy(&(ntEmulatedTarget.nti.nai.abtAts[4]), pbtTkt, szTk);
381 printf(
"We will emulate:\n");
382 print_nfc_target(&ntEmulatedTarget,
false);
386 pndTarget =
nfc_open(context, connstrings[1]);
388 pndTarget =
nfc_open(context, connstrings[0]);
390 if (pndTarget == NULL) {
391 printf(
"Error opening NFC emulator device\n");
392 if (!target_only_mode) {
400 if (
nfc_target_init(pndTarget, &ntEmulatedTarget, abtCapdu,
sizeof(abtCapdu), 0) < 0) {
401 ERR(
"%s",
"Initialization of NFC emulator failed");
402 if (!target_only_mode) {
409 printf(
"%s\n",
"Done, relaying frames now!");
415 if (!initiator_only_mode) {
418 nfc_perror(pndTarget,
"nfc_target_receive_bytes");
419 if (!target_only_mode) {
426 szCapduLen = (size_t) res;
427 if (target_only_mode) {
428 if (print_hex_fd4(abtCapdu, szCapduLen,
"C-APDU") < 0) {
429 fprintf(stderr,
"Error while printing C-APDU to FD4\n");
436 if (scan_hex_fd3(abtCapdu, &szCapduLen,
"C-APDU") < 0) {
437 fprintf(stderr,
"Error while scanning C-APDU from FD3\n");
445 printf(
"Forwarding C-APDU: ");
446 print_hex(abtCapdu, szCapduLen);
449 if (!target_only_mode) {
454 szRapduLen = (size_t) res;
458 if (scan_hex_fd3(abtRapdu, &szRapduLen,
"R-APDU") < 0) {
459 fprintf(stderr,
"Error while scanning R-APDU from FD3\n");
468 if (waiting_time > 0) {
470 printf(
"Waiting %is to simulate longer relay...\n", waiting_time);
476 printf(
"Forwarding R-APDU: ");
477 print_hex(abtRapdu, szRapduLen);
479 if (!initiator_only_mode) {
482 nfc_perror(pndTarget,
"nfc_target_send_bytes");
483 if (!target_only_mode) {
486 if (!initiator_only_mode) {
494 if (print_hex_fd4(abtRapdu, szRapduLen,
"R-APDU") < 0) {
495 fprintf(stderr,
"Error while printing R-APDU to FD4\n");
504 if (!target_only_mode) {
507 if (!initiator_only_mode) {