Ejemplo n.º 1
1
int NFC_Mifare_Classic(int argc, const char *argv[]) //! Lecture - Écriture d'une carte MIFARE Classic
{
    action_t atAction = ACTION_USAGE;
    uint8_t *pbtUID;
    int    unlock = 0;
    if (argc < 2)
    {
        sprintf(message_erreur,"Syntaxe incorrecte !");
        return EXIT_FAILURE; //! Échec !
    }
    const char *command = argv[1];
    if (strcmp(command, "r") == 0 || strcmp(command, "R") == 0)
    {
        if (argc < 4)
        {
            sprintf(message_erreur,"Syntaxe incorrecte !");
            return EXIT_FAILURE; //! Échec !
        }
        atAction = ACTION_READ;
        if (strcmp(command, "R") == 0)
        {
            unlock = 1;
        }
        bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
        bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
        bUseKeyFile = (argc > 4);
        bForceKeyFile = ((argc > 5) && (strcmp((char *)argv[5], "f") == 0));
    }
    else if (strcmp(command, "w") == 0 || strcmp(command, "W") == 0)
    {
        if (argc < 4)
        {
            sprintf(message_erreur,"Syntaxe incorrecte !");
            return EXIT_FAILURE; //! Échec !
        }
        atAction = ACTION_WRITE;
        if (strcmp(command, "W") == 0)
        {
            unlock = 1;
        }
        bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
        bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
        bUseKeyFile = (argc > 4);
        bForceKeyFile = ((argc > 5) && (strcmp((char *)argv[5], "f") == 0));
    }
    if (atAction == ACTION_USAGE)
    {
        sprintf(message_erreur,"Syntaxe incorrecte !");
        return EXIT_FAILURE; //! Échec !
    }
    //! We don't know yet the card size so let's read only the UID from the keyfile for the moment
    if (bUseKeyFile)
    {
        FILE *pfKeys = fopen(argv[4], "rb");
        if (pfKeys == NULL)
        {
            sprintf(message_erreur,"Could not open keys file: %s\n", argv[4]);
            return EXIT_FAILURE; //! Échec !
        }
        if (fread(&mtKeys, 1, 4, pfKeys) != 4)
        {
            sprintf(message_erreur,"Could not read UID from key file: %s !", argv[4]);
            fclose(pfKeys);
            return EXIT_FAILURE; //! Échec !
        }
        fclose(pfKeys);
    }
    nfc_init(&context);
    if (context == NULL)
    {
        sprintf(message_erreur,"Unable to init libnfc (malloc) !");
        return EXIT_FAILURE; //! Échec !
    }
    //! Try to open the NFC reader
    pnd = nfc_open(context, NULL);
    if (pnd == NULL)
    {
        sprintf(message_erreur,"Error opening NFC reader !");
        nfc_exit(context);
        return EXIT_FAILURE; //! Échec !
    }
    if (nfc_initiator_init(pnd) < 0)
    {
        nfc_perror(pnd, "nfc_initiator_init");
        nfc_strerror_r(pnd, message_erreur, TAILLE_MESSAGE_ERREUR);
        nfc_close(pnd);
        nfc_exit(context);
        return EXIT_FAILURE; //! Échec !
    };
    //! Let the reader only try once to find a tag
    if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0)
    {
        nfc_perror(pnd, "nfc_device_set_property_bool");
        nfc_strerror_r(pnd, message_erreur, TAILLE_MESSAGE_ERREUR);
        nfc_close(pnd);
        nfc_exit(context);
        return EXIT_FAILURE; //! Échec !
    }
    //! Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
    nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false);
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"NFC reader: %s opened\n", nfc_device_get_name(pnd));
    #endif
    //! Try to find a MIFARE Classic tag
    if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0)
    {
        sprintf(message_erreur,"Error: no tag was found !");
        nfc_close(pnd);
        nfc_exit(context);
        return EXIT_FAILURE; //! Échec !
    }
    //! Test if we are dealing with a MIFARE compatible tag
    if ((nt.nti.nai.btSak & 0x08) == 0)
    {
        #ifdef DEBUG_PRINTF
        fprintf(stderr,"Warning: tag is probably not a MFC !");
        #endif
    }
    //! Get the info from the current tag
    pbtUID = nt.nti.nai.abtUid;
    if (bUseKeyFile)
    {
        uint8_t fileUid[4];
        memcpy(fileUid, mtKeys.amb[0].mbm.abtUID, 4);
        //! Compare if key dump UID is the same as the current tag UID, at least for the first 4 bytes
        if (memcmp(pbtUID, fileUid, 4) != 0)
        {
            #ifdef DEBUG_PRINTF
            fprintf(stderr,"Expected MIFARE Classic card with UID starting as: %02x%02x%02x%02x\n", fileUid[0], fileUid[1], fileUid[2], fileUid[3]);
            fprintf(stderr,"Got card with UID starting as:                     %02x%02x%02x%02x\n", pbtUID[0], pbtUID[1], pbtUID[2], pbtUID[3]);
            #endif
            if (! bForceKeyFile)
            {
                sprintf(message_erreur,"Aborting !");
                nfc_close(pnd);
                nfc_exit(context);
                return EXIT_FAILURE; //! Échec !
            }
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"Found MIFARE Classic card:\n");
    #endif
    print_nfc_target(&nt, false);
    //! Guessing size
    if ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x02)
        //! 4K
        uiBlocks = 0xff;
    else if ((nt.nti.nai.btSak & 0x01) == 0x01)
        //! 320b
        uiBlocks = 0x13;
    else
        //! 1K/2K, checked through RATS
        uiBlocks = 0x3f;
    //! Testing RATS
    int res;
    if ((res = get_rats()) > 0)
    {
        if ((res >= 10) && (abtRx[5] == 0xc1) && (abtRx[6] == 0x05) && (abtRx[7] == 0x2f) && (abtRx[8] == 0x2f) && ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x00))
        {
            //! MIFARE Plus 2K
            uiBlocks = 0x7f;
        }
        //! Chinese magic emulation card, ATS=0978009102:dabc1910
        if ((res == 9)  && (abtRx[5] == 0xda) && (abtRx[6] == 0xbc) && (abtRx[7] == 0x19) && (abtRx[8] == 0x10))
        {
            magic2 = true;
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"Guessing size: seems to be a %i-byte card\n", (uiBlocks + 1) * 16);
    #endif
    if (bUseKeyFile)
    {
        FILE *pfKeys = fopen(argv[4], "rb");
        if (pfKeys == NULL)
        {
            sprintf(message_erreur,"Could not open keys file: %s !", argv[4]);
            return EXIT_FAILURE; //! Échec !
        }
        if (fread(&mtKeys, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfKeys) != (uiBlocks + 1) * sizeof(mifare_classic_block))
        {
            sprintf(message_erreur,"Could not read keys file: %s !", argv[4]);
            fclose(pfKeys);
            return EXIT_FAILURE; //! Échec !
        }
        fclose(pfKeys);
    }
    if (atAction == ACTION_READ)
    {
        memset(&mtDump, 0x00, sizeof(mtDump));
    }
    else
    {
        FILE *pfDump = fopen(argv[3], "rb");
        if (pfDump == NULL)
        {
            sprintf(message_erreur,"Could not open dump file: %s !", argv[3]);
            return EXIT_FAILURE; //! Échec !
        }
        if (fread(&mtDump, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfDump) != (uiBlocks + 1) * sizeof(mifare_classic_block))
        {
            sprintf(message_erreur,"Could not read dump file: %s !", argv[3]);
            fclose(pfDump);
            return EXIT_FAILURE; //! Échec !
        }
        fclose(pfDump);
    }
    if (atAction == ACTION_READ)
    {
        if (read_card(unlock))
        {
            #ifdef DEBUG_PRINTF
            fprintf(stderr,"Writing data to file: %s ...", argv[3]);
            #endif
            fflush(stdout);
            FILE *pfDump = fopen(argv[3], "wb");
            if (pfDump == NULL)
            {
                sprintf(message_erreur,"Could not open dump file: %s !", argv[3]);
                nfc_close(pnd);
                nfc_exit(context);
                return EXIT_FAILURE; //! Échec !
            }
            if (fwrite(&mtDump, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfDump) != ((uiBlocks + 1) * sizeof(mifare_classic_block)))
            {
                sprintf(message_erreur,"\nCould not write to file: %s !", argv[3]);
                fclose(pfDump);
                nfc_close(pnd);
                nfc_exit(context);
                return EXIT_FAILURE; //! Échec !
            }
            #ifdef DEBUG_PRINTF
            fprintf(stderr,"Done.\n");
            #endif
            fclose(pfDump);
        }
        else
        {
            nfc_close(pnd);
            nfc_exit(context);
            return EXIT_FAILURE;
        }
    }
    else if (atAction == ACTION_WRITE)
    {
        write_card(unlock);
    }
    nfc_close(pnd);
    nfc_exit(context);
    return EXIT_SUCCESS; //! Succès !
}
Ejemplo n.º 2
0
int
main(int argc, const char *argv[])
{
  (void) argc;
  (void) argv;

  nfc_context *context;
  nfc_init(&context);
  if (context == NULL) {
    ERR("Unable to init libnfc (malloc)");
    exit(EXIT_FAILURE);
  }

  // Display libnfc version
  const char *acLibnfcVersion = nfc_version();
  printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);

  // Open using the first available NFC device
  nfc_device *pnd;
  pnd = nfc_open(context, NULL);

  if (pnd == NULL) {
    ERR("%s", "Unable to open NFC device.");
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  printf("NFC device: %s opened\n", nfc_device_get_name(pnd));

  // Print the example's menu
  printf("\nSelect the communication mode:\n");
  printf("[1] Virtual card mode.\n");
  printf("[2] Wired card mode.\n");
  printf("[3] Dual card mode.\n");
  printf(">> ");

  // Take user's choice
  int input = getchar();
  printf("\n");
  if ((input < '1') || (input > '3')) {
    ERR("%s", "Invalid selection.");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  /*
   * '1' -> "Virtual mode" (0x02)
   * '2' -> "Wired card" (0x03)
   * '3' -> "Dual card" (0x04)
   */
  int iMode = input - '0' + 0x01;
  pn532_sam_mode mode = iMode;

  // Connect with the SAM

  switch (mode) {
    case PSM_VIRTUAL_CARD: {
      // FIXME Its a private pn53x function
      if (pn532_SAMConfiguration(pnd, mode, 0) < 0) {
        nfc_perror(pnd, "pn53x_SAMConfiguration");
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      printf("Now the SAM is readable for 1 minute from an external reader.\n");
      wait_one_minute();
    }
    break;

    case PSM_WIRED_CARD: {
      // Set opened NFC device to initiator mode
      if (nfc_initiator_init_secure_element(pnd) < 0) {
        nfc_perror(pnd, "nfc_initiator_init_secure_element");
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }

      // Let the reader only try once to find a tag
      if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
        nfc_perror(pnd, "nfc_device_set_property_bool");
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      // Read the SAM's info
      const nfc_modulation nmSAM = {
        .nmt = NMT_ISO14443A,
        .nbr = NBR_106,
      };
      nfc_target nt;

      int res;
      if ((res = nfc_initiator_select_passive_target(pnd, nmSAM, NULL, 0, &nt)) < 0) {
        nfc_perror(pnd, "nfc_initiator_select_passive_target");
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      } else if (res == 0) {
        ERR("No SAM found.");
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      } else if (res == 1) {
        printf("The following ISO14443A tag (SAM) was found:\n");
        print_nfc_target(&nt, true);
      } else {
        ERR("%s", "More than one ISO14442 tag found as SAM.");
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
    }
    break;

    case PSM_DUAL_CARD: {
      // FIXME Its a private pn53x function
      if (pn532_SAMConfiguration(pnd, mode, 0) < 0) {
        nfc_perror(pnd, "pn53x_SAMConfiguration");
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      uint8_t  abtRx[MAX_FRAME_LEN];

      nfc_target nt = {
        .nm = {
          .nmt = NMT_ISO14443A,
          .nbr = NBR_UNDEFINED,
        },
        .nti = {
          .nai = {
            .abtAtqa = { 0x04, 0x00 },
            .abtUid = { 0x08, 0xad, 0xbe, 0xef },
            .btSak = 0x20,
            .szUidLen = 4,
            .szAtsLen = 0,
          },
        },
      };
Ejemplo n.º 3
0
int
main(int argc, char *argv[])
{
  int     arg;
  const char *acLibnfcVersion = nfc_version();
  nfc_target ntRealTarget;

  // Get commandline options
  for (arg = 1; arg < argc; arg++) {
    if (0 == strcmp(argv[arg], "-h")) {
      print_usage(argv);
      exit(EXIT_SUCCESS);
    } else if (0 == strcmp(argv[arg], "-q")) {
      quiet_output = true;
    } else if (0 == strcmp(argv[arg], "-t")) {
      printf("INFO: %s\n", "Target mode only.");
      initiator_only_mode = false;
      target_only_mode = true;
    } else if (0 == strcmp(argv[arg], "-i")) {
      printf("INFO: %s\n", "Initiator mode only.");
      initiator_only_mode = true;
      target_only_mode = false;
    } else if (0 == strcmp(argv[arg], "-s")) {
      printf("INFO: %s\n", "Swapping devices.");
      swap_devices = true;
    } else if (0 == strcmp(argv[arg], "-n")) {
      if (++arg == argc || (sscanf(argv[arg], "%10i", &waiting_time) < 1)) {
        ERR("Missing or wrong waiting time value: %s.", argv[arg]);
        print_usage(argv);
        exit(EXIT_FAILURE);
      }
      printf("Waiting time: %i secs.\n", waiting_time);
    } else {
      ERR("%s is not supported option.", argv[arg]);
      print_usage(argv);
      exit(EXIT_FAILURE);
    }
  }

  // Display libnfc version
  printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);

#ifdef WIN32
  signal(SIGINT, (void (__cdecl *)(int)) intr_hdlr);
#else
  signal(SIGINT, intr_hdlr);
#endif

  nfc_context *context;
  nfc_init(&context);
  if (context == NULL) {
    ERR("Unable to init libnfc (malloc)");
    exit(EXIT_FAILURE);
  }

  nfc_connstring connstrings[MAX_DEVICE_COUNT];
  // List available devices
  size_t szFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT);

  if (initiator_only_mode || target_only_mode) {
    if (szFound < 1) {
      ERR("No device found");
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }
    if ((fd3 = fdopen(3, "r")) == NULL) {
      ERR("Could not open file descriptor 3");
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }
    if ((fd4 = fdopen(4, "r")) == NULL) {
      ERR("Could not open file descriptor 4");
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }
  } else {
    if (szFound < 2) {
      ERR("%" PRIdPTR " device found but two opened devices are needed to relay NFC.", szFound);
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }
  }

  if (!target_only_mode) {
    // Try to open the NFC reader used as initiator
    // Little hack to allow using initiator no matter if
    // there is already a target used locally or not on the same machine:
    // if there is more than one readers opened we open the second reader
    // (we hope they're always detected in the same order)
    if ((szFound == 1) || swap_devices) {
      pndInitiator = nfc_open(context, connstrings[0]);
    } else {
      pndInitiator = nfc_open(context, connstrings[1]);
    }

    if (pndInitiator == NULL) {
      printf("Error opening NFC reader\n");
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }

    printf("NFC reader device: %s opened\n", nfc_device_get_name(pndInitiator));

    if (nfc_initiator_init(pndInitiator) < 0) {
      printf("Error: fail initializing initiator\n");
      nfc_close(pndInitiator);
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }

    // Try to find a ISO 14443-4A tag
    nfc_modulation nm = {
      .nmt = NMT_ISO14443A,
      .nbr = NBR_106,
    };
    if (nfc_initiator_select_passive_target(pndInitiator, nm, NULL, 0, &ntRealTarget) <= 0) {
      printf("Error: no tag was found\n");
      nfc_close(pndInitiator);
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }

    printf("Found tag:\n");
    print_nfc_target(&ntRealTarget, false);
    if (initiator_only_mode) {
      if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen, "UID") < 0) {
        fprintf(stderr, "Error while printing UID to FD4\n");
        nfc_close(pndInitiator);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      if (print_hex_fd4(ntRealTarget.nti.nai.abtAtqa, 2, "ATQA") < 0) {
        fprintf(stderr, "Error while printing ATQA to FD4\n");
        nfc_close(pndInitiator);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      if (print_hex_fd4(&(ntRealTarget.nti.nai.btSak), 1, "SAK") < 0) {
        fprintf(stderr, "Error while printing SAK to FD4\n");
        nfc_close(pndInitiator);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      if (print_hex_fd4(ntRealTarget.nti.nai.abtAts, ntRealTarget.nti.nai.szAtsLen, "ATS") < 0) {
        fprintf(stderr, "Error while printing ATS to FD4\n");
        nfc_close(pndInitiator);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
    }
  }
  if (initiator_only_mode) {
    printf("Hint: tag <---> *INITIATOR* (relay) <-FD3/FD4-> target (relay) <---> original reader\n\n");
  } else if (target_only_mode) {
    printf("Hint: tag <---> initiator (relay) <-FD3/FD4-> *TARGET* (relay) <---> original reader\n\n");
  } else {
    printf("Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n");
  }
  if (!initiator_only_mode) {
    nfc_target ntEmulatedTarget = {
      .nm = {
        .nmt = NMT_ISO14443A,
        .nbr = NBR_106,
      },
    };
    if (target_only_mode) {
      size_t foo;
      if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtUid, &(ntEmulatedTarget.nti.nai.szUidLen), "UID") < 0) {
        fprintf(stderr, "Error while scanning UID from FD3\n");
        nfc_close(pndInitiator);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAtqa, &foo, "ATQA") < 0) {
        fprintf(stderr, "Error while scanning ATQA from FD3\n");
        nfc_close(pndInitiator);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      if (scan_hex_fd3(&(ntEmulatedTarget.nti.nai.btSak), &foo, "SAK") < 0) {
        fprintf(stderr, "Error while scanning SAK from FD3\n");
        nfc_close(pndInitiator);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAts, &(ntEmulatedTarget.nti.nai.szAtsLen), "ATS") < 0) {
        fprintf(stderr, "Error while scanning ATS from FD3\n");
        nfc_close(pndInitiator);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
    } else {
      ntEmulatedTarget.nti = ntRealTarget.nti;
    }
    // We can only emulate a short UID, so fix length & ATQA bit:
    ntEmulatedTarget.nti.nai.szUidLen = 4;
    ntEmulatedTarget.nti.nai.abtAtqa[1] &= (0xFF - 0x40);
    // First byte of UID is always automatically replaced by 0x08 in this mode anyway
    ntEmulatedTarget.nti.nai.abtUid[0] = 0x08;
    // ATS is always automatically replaced by PN532, we've no control on it:
    // ATS = (05) 75 33 92 03
    //       (TL) T0 TA TB TC
    //             |  |  |  +-- CID supported, NAD supported
    //             |  |  +----- FWI=9 SFGI=2 => FWT=154ms, SFGT=1.21ms
    //             |  +-------- DR=2,4 DS=2,4 => supports 106, 212 & 424bps in both directions
    //             +----------- TA,TB,TC, FSCI=5 => FSC=64
    // It seems hazardous to tell we support NAD if the tag doesn't support NAD but I don't know how to disable it
    // PC/SC pseudo-ATR = 3B 80 80 01 01 if there is no historical bytes

    // Creates ATS and copy max 48 bytes of Tk:
    uint8_t *pbtTk;
    size_t szTk;
    pbtTk = iso14443a_locate_historical_bytes(ntEmulatedTarget.nti.nai.abtAts, ntEmulatedTarget.nti.nai.szAtsLen, &szTk);
    szTk = (szTk > 48) ? 48 : szTk;
    uint8_t pbtTkt[48];
    memcpy(pbtTkt, pbtTk, szTk);
    ntEmulatedTarget.nti.nai.abtAts[0] = 0x75;
    ntEmulatedTarget.nti.nai.abtAts[1] = 0x33;
    ntEmulatedTarget.nti.nai.abtAts[2] = 0x92;
    ntEmulatedTarget.nti.nai.abtAts[3] = 0x03;
    ntEmulatedTarget.nti.nai.szAtsLen = 4 + szTk;
    memcpy(&(ntEmulatedTarget.nti.nai.abtAts[4]), pbtTkt, szTk);

    printf("We will emulate:\n");
    print_nfc_target(&ntEmulatedTarget, false);

    // Try to open the NFC emulator device
    if (swap_devices) {
      pndTarget = nfc_open(context, connstrings[1]);
    } else {
      pndTarget = nfc_open(context, connstrings[0]);
    }
    if (pndTarget == NULL) {
      printf("Error opening NFC emulator device\n");
      if (!target_only_mode) {
        nfc_close(pndInitiator);
      }
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }

    printf("NFC emulator device: %s opened\n", nfc_device_get_name(pndTarget));
    if (nfc_target_init(pndTarget, &ntEmulatedTarget, abtCapdu, sizeof(abtCapdu), 0) < 0) {
      ERR("%s", "Initialization of NFC emulator failed");
      if (!target_only_mode) {
        nfc_close(pndInitiator);
      }
      nfc_close(pndTarget);
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }
    printf("%s\n", "Done, relaying frames now!");
  }
Ejemplo n.º 4
0
int
main(int argc, const char *argv[])
{
  if (argc < 2) {
    usage(); 
    exit(EXIT_FAILURE);   
  } 

  parseopts(argv[1]);  

  nfc_init(&context);
  if (context == NULL) {
    ERR("Unable to init libnfc (malloc)");
    exit(EXIT_FAILURE);
  }

// Try to open the NFC reader
  pnd = nfc_open(context, NULL);
  if (pnd == NULL) {
    ERR("Error opening NFC reader");
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  if (nfc_initiator_init(pnd) < 0) {
    nfc_perror(pnd, "nfc_initiator_init");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  };

// Let the reader only try once to find a tag
  if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
  if (nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false) < 0) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
  // Configure the CRC
  if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
  // Use raw send/receive methods
  if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));

// Try to find a MIFARE Classic tag
  if (select_target(pnd, &nt) <= 0) {
    printf("Error: no tag was found\n");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
// Test if we are dealing with a MIFARE compatible tag
  if ((nt.nti.nai.btSak & 0x08) == 0) {
    printf("Warning: tag is probably not a MFC!\n");
  }

  printf("Found MIFARE Classic card:\n");
  nt.nm = nmMifare;
  print_nfc_target(&nt, false);


// Guessing size
  if ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x02)
// 4K
    uiBlocks = 0xff;
  else if ((nt.nti.nai.btSak & 0x01) == 0x01)
// 320b
    uiBlocks = 0x13;
  else
// 1K/2K, checked through RATS
    uiBlocks = 0x3f;

    printf("Guessing size: seems to be a %i-byte card\n", (uiBlocks + 1) * 16);

  if (parse_card()) {
	printf("Done, %d blocks read.\n", uiBlocks + 1);
	fflush(stdout);
  }

  if(is_addv) if(!easy_add_value(0xff) || !parse_card()) printf("Failed Add Value!!\n");    

  printTag(&e); 

  nfc_close(pnd);
  nfc_exit(context);
  exit(EXIT_SUCCESS);
}