fix one too small
[RRG-proxmark3.git] / client / src / cmdwiegand.c
blob9fc06b6f97cc1aba4b4d66cf8e04a087068efd1a
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // Wiegand commands
17 //-----------------------------------------------------------------------------
18 #include "cmdwiegand.h"
20 #include <ctype.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include "cmdparser.h" // command_t
24 #include "cliparser.h"
25 #include "comms.h"
26 #include "pm3_cmd.h"
27 #include "protocols.h"
28 #include "parity.h" // oddparity
29 #include "cmdhflist.h" // annotations
30 #include "wiegand_formats.h"
31 #include "wiegand_formatutils.h"
32 #include "util.h"
34 static int CmdHelp(const char *Cmd);
36 int CmdWiegandList(const char *Cmd) {
38 CLIParserContext *ctx;
39 CLIParserInit(&ctx, "wiegand info",
40 "List available wiegand formats",
41 "wiegand list"
44 void *argtable[] = {
45 arg_param_begin,
46 arg_param_end
48 CLIExecWithReturn(ctx, Cmd, argtable, true);
49 CLIParserFree(ctx);
51 HIDListFormats();
52 return PM3_SUCCESS;
55 int CmdWiegandEncode(const char *Cmd) {
57 CLIParserContext *ctx;
58 CLIParserInit(&ctx, "wiegand encode",
59 "Encode wiegand formatted number to raw hex",
60 "wiegand encode --fc 101 --cn 1337 -> show all formats\n"
61 "wiegand encode -w H10301 --fc 101 --cn 1337 -> H10301 format "
64 void *argtable[] = {
65 arg_param_begin,
66 arg_u64_0(NULL, "fc", "<dec>", "facility number"),
67 arg_u64_1(NULL, "cn", "<dec>", "card number"),
68 arg_u64_0(NULL, "issue", "<dec>", "issue level"),
69 arg_u64_0(NULL, "oem", "<dec>", "OEM code"),
70 arg_str0("w", "wiegand", "<format>", "see `wiegand list` for available formats"),
71 arg_lit0(NULL, "pre", "add HID ProxII preamble to wiegand output"),
72 arg_param_end
74 CLIExecWithReturn(ctx, Cmd, argtable, true);
76 wiegand_card_t data;
77 memset(&data, 0, sizeof(wiegand_card_t));
79 data.FacilityCode = arg_get_u32_def(ctx, 1, 0);
80 data.CardNumber = arg_get_u64_def(ctx, 2, 0);
81 data.IssueLevel = arg_get_u32_def(ctx, 3, 0);
82 data.OEM = arg_get_u32_def(ctx, 4, 0);
84 int len = 0;
85 char format[16] = {0};
86 CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)format, sizeof(format), &len);
87 bool preamble = arg_get_lit(ctx, 6);
88 CLIParserFree(ctx);
90 int idx = -1;
91 if (len) {
92 idx = HIDFindCardFormat(format);
93 if (idx == -1) {
94 PrintAndLogEx(WARNING, "Unknown format: %s", format);
95 return PM3_EINVARG;
99 if (idx != -1) {
100 wiegand_message_t packed;
101 memset(&packed, 0, sizeof(wiegand_message_t));
102 if (HIDPack(idx, &data, &packed, preamble) == false) {
103 PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format.");
104 return PM3_ESOFT;
106 print_wiegand_code(&packed);
107 } else {
108 // try all formats and print only the ones that work.
109 HIDPackTryAll(&data, preamble);
111 return PM3_SUCCESS;
114 int CmdWiegandDecode(const char *Cmd) {
116 CLIParserContext *ctx;
117 CLIParserInit(&ctx, "wiegand decode",
118 "Decode raw hex or binary to wiegand format",
119 "wiegand decode --raw 2006f623ae"
122 void *argtable[] = {
123 arg_param_begin,
124 arg_str0("r", "raw", "<hex>", "raw hex to be decoded"),
125 arg_str0("b", "bin", "<bin>", "binary string to be decoded"),
126 arg_param_end
128 CLIExecWithReturn(ctx, Cmd, argtable, true);
129 int hlen = 0;
130 char hex[40] = {0};
131 CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)hex, sizeof(hex), &hlen);
133 int blen = 0;
134 uint8_t binarr[100] = {0x00};
135 int res = CLIParamBinToBuf(arg_get_str(ctx, 2), binarr, sizeof(binarr), &blen);
136 CLIParserFree(ctx);
138 if (res) {
139 PrintAndLogEx(FAILED, "Error parsing binary string");
140 return PM3_EINVARG;
143 uint32_t top = 0, mid = 0, bot = 0;
145 if (hlen) {
146 res = hexstring_to_u96(&top, &mid, &bot, hex);
147 if (res != hlen) {
148 PrintAndLogEx(ERR, "Hex string contains none hex chars");
149 return PM3_EINVARG;
151 } else if (blen) {
152 int n = binarray_to_u96(&top, &mid, &bot, binarr, blen);
153 if (n != blen) {
154 PrintAndLogEx(ERR, "Binary string contains none <0|1> chars");
155 return PM3_EINVARG;
157 PrintAndLogEx(INFO, "Input bin len... %d", blen);
158 } else {
159 PrintAndLogEx(ERR, "Empty input");
160 return PM3_EINVARG;
163 wiegand_message_t packed = initialize_message_object(top, mid, bot, blen);
164 HIDTryUnpack(&packed);
165 return PM3_SUCCESS;
168 static command_t CommandTable[] = {
169 {"help", CmdHelp, AlwaysAvailable, "This help"},
170 {"list", CmdWiegandList, AlwaysAvailable, "List available wiegand formats"},
171 {"encode", CmdWiegandEncode, AlwaysAvailable, "Encode to wiegand raw hex (currently for HID Prox)"},
172 {"decode", CmdWiegandDecode, AlwaysAvailable, "Convert raw hex to decoded wiegand format (currently for HID Prox)"},
173 {NULL, NULL, NULL, NULL}
176 static int CmdHelp(const char *Cmd) {
177 (void)Cmd; // Cmd is not used so far
178 CmdsHelp(CommandTable);
179 return PM3_SUCCESS;
182 int CmdWiegand(const char *Cmd) {
183 clearCommandBuffer();
184 return CmdsParse(CommandTable, Cmd);