65 #define MAX_FRAME_LEN 264
66 #define MAX_DEVICE_COUNT 2
68 static uint8_t abtCapdu[MAX_FRAME_LEN];
69 static size_t szCapduLen;
70 static uint8_t abtRapdu[MAX_FRAME_LEN];
71 static size_t szRapduLen;
74 static bool quitting =
false;
75 static bool quiet_output =
false;
76 static bool initiator_only_mode =
false;
77 static bool target_only_mode =
false;
78 static bool swap_devices =
false;
79 static unsigned int waiting_time = 0;
87 printf(
"\nQuitting...\n");
88 printf(
"Please send a last command to the emulator to quit properly.\n");
94 print_usage(
char *argv[])
96 printf(
"Usage: %s [OPTIONS]\n", argv[0]);
98 printf(
"\t-h\tHelp. Print this message.\n");
99 printf(
"\t-q\tQuiet mode. Suppress printing of relayed data (improves timing).\n");
100 printf(
"\t-t\tTarget mode only (the one on reader side). Data expected from FD3 to FD4.\n");
101 printf(
"\t-i\tInitiator mode only (the one on tag side). Data expected from FD3 to FD4.\n");
102 printf(
"\t-n N\tAdds a waiting time of N seconds (integer) in the relay to mimic long distance.\n");
105 static int print_hex_fd4(
const uint8_t *pbtData,
const size_t szBytes,
const char *pchPrefix)
108 if (szBytes > MAX_FRAME_LEN) {
111 if (fprintf(fd4,
"#%s %04" PRIxPTR
": ", pchPrefix, szBytes) < 0) {
115 for (szPos = 0; szPos < szBytes; szPos++) {
116 if (fprintf(fd4,
"%02x ", pbtData[szPos]) < 0) {
120 if (fprintf(fd4,
"\n") < 0) {
127 static int scan_hex_fd3(uint8_t *pbtData,
size_t *pszBytes,
const char *pchPrefix)
130 unsigned int uiBytes;
135 while ((c = fgetc(fd3)) !=
'#') {
140 strncpy(pchScan, pchPrefix, 250);
141 pchScan[
sizeof(pchScan) - 1] =
'\0';
142 strcat(pchScan,
" %04x:");
143 if (fscanf(fd3, pchScan, &uiBytes) < 1) {
147 if (*pszBytes > MAX_FRAME_LEN) {
150 for (szPos = 0; szPos < *pszBytes; szPos++) {
151 if (fscanf(fd3,
"%02x", &uiData) < 1) {
154 pbtData[szPos] = uiData;
160 main(
int argc,
char *argv[])
167 for (arg = 1; arg < argc; arg++) {
168 if (0 == strcmp(argv[arg],
"-h")) {
171 }
else if (0 == strcmp(argv[arg],
"-q")) {
173 }
else if (0 == strcmp(argv[arg],
"-t")) {
174 printf(
"INFO: %s\n",
"Target mode only.");
175 initiator_only_mode =
false;
176 target_only_mode =
true;
177 }
else if (0 == strcmp(argv[arg],
"-i")) {
178 printf(
"INFO: %s\n",
"Initiator mode only.");
179 initiator_only_mode =
true;
180 target_only_mode =
false;
181 }
else if (0 == strcmp(argv[arg],
"-s")) {
182 printf(
"INFO: %s\n",
"Swapping devices.");
184 }
else if (0 == strcmp(argv[arg],
"-n")) {
185 if (++arg == argc || (sscanf(argv[arg],
"%10u", &waiting_time) < 1)) {
186 ERR(
"Missing or wrong waiting time value: %s.", argv[arg]);
190 printf(
"Waiting time: %u secs.\n", waiting_time);
192 ERR(
"%s is not supported option.", argv[arg]);
199 printf(
"%s uses libnfc %s\n", argv[0], acLibnfcVersion);
202 signal(SIGINT, (
void (__cdecl *)(
int)) intr_hdlr);
204 signal(SIGINT, intr_hdlr);
209 if (context == NULL) {
210 ERR(
"Unable to init libnfc (malloc)");
218 if (initiator_only_mode || target_only_mode) {
220 ERR(
"No device found");
224 if ((fd3 = fdopen(3,
"r")) == NULL) {
225 ERR(
"Could not open file descriptor 3");
229 if ((fd4 = fdopen(4,
"r")) == NULL) {
230 ERR(
"Could not open file descriptor 4");
236 ERR(
"%" PRIdPTR
" device found but two opened devices are needed to relay NFC.", szFound);
242 if (!target_only_mode) {
248 if ((szFound == 1) || swap_devices) {
249 pndInitiator =
nfc_open(context, connstrings[0]);
251 pndInitiator =
nfc_open(context, connstrings[1]);
254 if (pndInitiator == NULL) {
255 printf(
"Error opening NFC reader\n");
263 printf(
"Error: fail initializing initiator\n");
271 .nmt = NMT_ISO14443A,
275 printf(
"Error: no tag was found\n");
281 printf(
"Found tag:\n");
282 print_nfc_target(&ntRealTarget,
false);
283 if (initiator_only_mode) {
284 if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen,
"UID") < 0) {
285 fprintf(stderr,
"Error while printing UID to FD4\n");
290 if (print_hex_fd4(ntRealTarget.nti.nai.abtAtqa, 2,
"ATQA") < 0) {
291 fprintf(stderr,
"Error while printing ATQA to FD4\n");
296 if (print_hex_fd4(&(ntRealTarget.nti.nai.btSak), 1,
"SAK") < 0) {
297 fprintf(stderr,
"Error while printing SAK to FD4\n");
302 if (print_hex_fd4(ntRealTarget.nti.nai.abtAts, ntRealTarget.nti.nai.szAtsLen,
"ATS") < 0) {
303 fprintf(stderr,
"Error while printing ATS to FD4\n");
310 if (initiator_only_mode) {
311 printf(
"Hint: tag <---> *INITIATOR* (relay) <-FD3/FD4-> target (relay) <---> original reader\n\n");
312 }
else if (target_only_mode) {
313 printf(
"Hint: tag <---> initiator (relay) <-FD3/FD4-> *TARGET* (relay) <---> original reader\n\n");
315 printf(
"Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n");
317 if (!initiator_only_mode) {
320 .nmt = NMT_ISO14443A,
324 if (target_only_mode) {
326 if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtUid, &(ntEmulatedTarget.nti.nai.szUidLen),
"UID") < 0) {
327 fprintf(stderr,
"Error while scanning UID from FD3\n");
332 if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAtqa, &foo,
"ATQA") < 0) {
333 fprintf(stderr,
"Error while scanning ATQA from FD3\n");
338 if (scan_hex_fd3(&(ntEmulatedTarget.nti.nai.btSak), &foo,
"SAK") < 0) {
339 fprintf(stderr,
"Error while scanning SAK from FD3\n");
344 if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAts, &(ntEmulatedTarget.nti.nai.szAtsLen),
"ATS") < 0) {
345 fprintf(stderr,
"Error while scanning ATS from FD3\n");
351 ntEmulatedTarget.nti = ntRealTarget.nti;
354 ntEmulatedTarget.nti.nai.szUidLen = 4;
355 ntEmulatedTarget.nti.nai.abtAtqa[1] &= (0xFF - 0x40);
357 ntEmulatedTarget.nti.nai.abtUid[0] = 0x08;
371 pbtTk = iso14443a_locate_historical_bytes(ntEmulatedTarget.nti.nai.abtAts, ntEmulatedTarget.nti.nai.szAtsLen, &szTk);
372 szTk = (szTk > 48) ? 48 : szTk;
374 memcpy(pbtTkt, pbtTk, szTk);
375 ntEmulatedTarget.nti.nai.abtAts[0] = 0x75;
376 ntEmulatedTarget.nti.nai.abtAts[1] = 0x33;
377 ntEmulatedTarget.nti.nai.abtAts[2] = 0x92;
378 ntEmulatedTarget.nti.nai.abtAts[3] = 0x03;
379 ntEmulatedTarget.nti.nai.szAtsLen = 4 + szTk;
380 memcpy(&(ntEmulatedTarget.nti.nai.abtAts[4]), pbtTkt, szTk);
382 printf(
"We will emulate:\n");
383 print_nfc_target(&ntEmulatedTarget,
false);
387 pndTarget =
nfc_open(context, connstrings[1]);
389 pndTarget =
nfc_open(context, connstrings[0]);
391 if (pndTarget == NULL) {
392 printf(
"Error opening NFC emulator device\n");
393 if (!target_only_mode) {
401 if (
nfc_target_init(pndTarget, &ntEmulatedTarget, abtCapdu,
sizeof(abtCapdu), 0) < 0) {
402 ERR(
"%s",
"Initialization of NFC emulator failed");
403 if (!target_only_mode) {
410 printf(
"%s\n",
"Done, relaying frames now!");
416 if (!initiator_only_mode) {
419 nfc_perror(pndTarget,
"nfc_target_receive_bytes");
420 if (!target_only_mode) {
427 szCapduLen = (size_t) res;
428 if (target_only_mode) {
429 if (print_hex_fd4(abtCapdu, szCapduLen,
"C-APDU") < 0) {
430 fprintf(stderr,
"Error while printing C-APDU to FD4\n");
437 if (scan_hex_fd3(abtCapdu, &szCapduLen,
"C-APDU") < 0) {
438 fprintf(stderr,
"Error while scanning C-APDU from FD3\n");
446 printf(
"Forwarding C-APDU: ");
447 print_hex(abtCapdu, szCapduLen);
450 if (!target_only_mode) {
455 szRapduLen = (size_t) res;
459 if (scan_hex_fd3(abtRapdu, &szRapduLen,
"R-APDU") < 0) {
460 fprintf(stderr,
"Error while scanning R-APDU from FD3\n");
469 if (waiting_time != 0) {
471 printf(
"Waiting %us to simulate longer relay...\n", waiting_time);
477 printf(
"Forwarding R-APDU: ");
478 print_hex(abtRapdu, szRapduLen);
480 if (!initiator_only_mode) {
483 nfc_perror(pndTarget,
"nfc_target_send_bytes");
484 if (!target_only_mode) {
487 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) {