sygcpp.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. /**
  2. *
  3. * IRC: irc.ilita.i2p port 6667 || 303:60d4:3d32:a2b9::3 port 16667
  4. * general channels: #ru and #howtoygg
  5. *
  6. * acetone (default) git: notabug.org/acetone/SimpleYggGen-CPP
  7. * Vort (member) git: notabug.org/Vort/SimpleYggGen-CPP
  8. *
  9. * developers: Vort, acetone, R4SAS, lialh4, filarius, orignal
  10. * developers team, 2020 (c) GPLv3
  11. *
  12. */
  13. #include <x86intrin.h>
  14. #include <string.h> // memcmp
  15. #include <sodium.h> // библиотека libsodium
  16. #include <iostream> // вывод на экран
  17. #include <string>
  18. #include <sstream>
  19. #include <fstream> // файловые потоки
  20. #include <iomanip> // форматированный вывод строк
  21. #include <bitset> // побитовое чтение
  22. #include <vector>
  23. #include <thread> // многопоточность
  24. #include <mutex> // блокирование данных при многопоточности
  25. #include <chrono> // для вычисления скорости
  26. #include <ctime>
  27. #include <regex> // регулярные выражения
  28. #ifdef _WIN32 // преобразование в IPv6
  29. #include <ws2tcpip.h>
  30. #else
  31. #include <arpa/inet.h>
  32. #endif
  33. #include "x25519.h"
  34. #include "sha512.h"
  35. #include "cppcodec/base32_rfc4648.hpp"
  36. #define BLOCKSIZE 10000
  37. //#define SELF_CHECK // debug
  38. void Intro()
  39. {
  40. std::cout <<
  41. std::endl <<
  42. " +--------------------------------------------------------------------------+" << std::endl <<
  43. " | [ SimpleYggGen C++ 3.4-subnetlover ] |" << std::endl <<
  44. " | X25519 -> SHA512 -> IPv6 -> Meshname |" << std::endl <<
  45. " | notabug.org/acetone/SimpleYggGen-CPP |" << std::endl <<
  46. " | |" << std::endl <<
  47. " | GPLv3 (c) 2020 |" << std::endl <<
  48. " +--------------------------------------------------------------------------+" << std::endl <<
  49. std::endl;
  50. }
  51. std::mutex mtx;
  52. std::time_t sygstartedin = std::time(NULL); // для вывода времени работы
  53. int countsize = 0; // определяет периодичность вывода счетчика
  54. uint64_t block_count = 0; // количество вычисленных блоков
  55. uint64_t totalcountfortune = 0; // счетчик нахождений
  56. bool newline = false; // форматирует вывод после нахождения адреса
  57. std::chrono::steady_clock::duration blocks_duration(0);
  58. #include "basefiles.cpp"
  59. int getOnes(const unsigned char HashValue[crypto_hash_sha512_BYTES])
  60. {
  61. const int map[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
  62. int lOnes = 0; // кол-во лидирующих единиц
  63. for (int i = 0; i < 32; ++i) // всего 32 байта, т.к. лидирующих единиц больше быть не может (32*8 = 256 бит, а ff = 255)
  64. {
  65. for (int j = 0; j < 8; ++j)
  66. {
  67. if (HashValue[i] & map[j]) // сравниваем биты байта с таблицей единичек
  68. ++lOnes;
  69. else
  70. return lOnes;
  71. }
  72. }
  73. return -421; // это никогда не случится
  74. }
  75. /**
  76. * Функция getRawAddress получает
  77. * 1) количество лидирующих единиц;
  78. * 2) массив хэша sha512;
  79. * 3) unit8_t-массив из 16 байт, куда будет записан "сырой" IPv6 адрес.
  80. * Подсчет единиц, как и другие возможные операции с массивом хэша необходимо
  81. * осуществлять до обращения к данной функции, т.к. она не копирует исходный массив
  82. * хэша, а портит его во время работы.
  83. * Под "сырым" адресом понимается байтовая информация, которая затем преобразуется
  84. * в стринг IPv6 и/или meshname-домен.
  85. */
  86. void getRawAddress(int lErase, unsigned char * HashValue, uint8_t * rawAddr) // ожидается 64 и 16 байт
  87. {
  88. ++lErase; // лидирующие единицы и первый ноль
  89. int bitshift = lErase % 8;
  90. int start = lErase / 8;
  91. for(int i = start; i < start+15; ++i)
  92. {
  93. HashValue[i] <<= bitshift;
  94. HashValue[i] |= (HashValue[i+1] >> (8-bitshift));
  95. }
  96. rawAddr[0] = 0x02;
  97. rawAddr[1] = lErase - 1;
  98. for (int i = 0; i < 14; ++i)
  99. rawAddr[i + 2] = HashValue[i+start];
  100. }
  101. std::string getAddress(const uint8_t * rawAddr)
  102. {
  103. char ipStrBuf[46];
  104. inet_ntop(AF_INET6, rawAddr, ipStrBuf, 46);
  105. return std::string(ipStrBuf);
  106. }
  107. std::string getMeshname(const uint8_t * rawAddr)
  108. {
  109. return std::string(cppcodec::base32_rfc4648::encode(rawAddr, 16));
  110. }
  111. /**
  112. * pickupStringForMeshname получает человекочитаемую строку
  113. * типа fsdasdaklasdgdas.meshname и возвращает значение, пригодное
  114. * для поиска по meshname-строке: удаляет возможную доменную зону
  115. * (всё после точки и саму точку), а также делает все буквы
  116. * заглавными.
  117. */
  118. std::string pickupStringForMeshname(std::string str)
  119. {
  120. bool dot = false;
  121. std::string::iterator delend;
  122. for (auto it = str.begin(); it != str.end(); it++)
  123. {
  124. // делаем все буквы заглавными для обработки
  125. *it = toupper(*it);
  126. if(*it == '.') {
  127. delend = it;
  128. dot = true;
  129. }
  130. }
  131. if(dot)
  132. for (auto it = str.end(); it != delend; it--)
  133. str.pop_back(); // удаляем доменную зону
  134. return str;
  135. }
  136. /**
  137. * pickupMeshnameForOutput получает сырое base32 значение
  138. * типа KLASJFHASSA7979====== и возвращает meshname-домен:
  139. * делает все символы строчными и удаляет паддинги ('='),
  140. * а также добавляет доменную зону ".meshname".
  141. */
  142. std::string pickupMeshnameForOutput(std::string str)
  143. {
  144. for (auto it = str.begin(); it != str.end(); it++) // делаем все буквы строчными для вывода
  145. *it = tolower(*it);
  146. for (auto it = str.end(); *(it-1) == '='; it--)
  147. str.pop_back(); // удаляем символы '=' в конце адреса
  148. return str + ".meshname";
  149. }
  150. /**
  151. * decodeMeshToIP получает строковое значение сырого base32
  152. * кода типа KLASJFHASSA7979====== и возвращает IPv6-стринг.
  153. */
  154. std::string decodeMeshToIP(const std::string str)
  155. {
  156. std::string mesh = pickupStringForMeshname(str) + "======"; // 6 паддингов - норма для IPv6 адреса
  157. std::vector<uint8_t> raw = cppcodec::base32_rfc4648::decode(mesh);
  158. uint8_t rawAddr[16];
  159. for(int i = 0; i < 16; ++i)
  160. rawAddr[i] = raw[i];
  161. return std::string(getAddress(rawAddr));
  162. }
  163. void subnetCheck()
  164. {
  165. if(conf.str_search[0] == '3') // замена 300::/64 на целевой 200::/7
  166. conf.str_search[0] = '2';
  167. }
  168. bool convertStrToRaw(std::string str, uint8_t * array)
  169. {
  170. bool result = inet_pton(AF_INET6, str.c_str(), (void*)array);
  171. return result;
  172. }
  173. void logStatistics()
  174. {
  175. if (++block_count % countsize == 0)
  176. {
  177. auto timedays = (std::time(NULL) - sygstartedin) / 86400;
  178. auto timehours = ((std::time(NULL) - sygstartedin) - (timedays * 86400)) / 3600;
  179. auto timeminutes = ((std::time(NULL) - sygstartedin) - (timedays * 86400) - (timehours * 3600)) / 60;
  180. auto timeseconds = (std::time(NULL) - sygstartedin) - (timedays * 86400) - (timehours * 3600) - (timeminutes * 60);
  181. std::chrono::duration<double, std::milli> df = blocks_duration;
  182. blocks_duration = std::chrono::steady_clock::duration::zero();
  183. int khs = conf.proc * countsize * BLOCKSIZE / df.count();
  184. std::cout <<
  185. " kH/s: [" << std::setw(7) << std::setfill('_') << khs <<
  186. "] Total: [" << std::setw(19) << block_count * BLOCKSIZE <<
  187. "] Found: [" << std::setw(3) << totalcountfortune <<
  188. "] Time: [" << timedays << ":" << std::setw(2) << std::setfill('0') <<
  189. timehours << ":" << std::setw(2) << timeminutes << ":" << std::setw(2) << timeseconds << "]" << std::endl;
  190. newline = true;
  191. }
  192. }
  193. std::string hexArrayToString(const uint8_t* bytes, int length)
  194. {
  195. std::stringstream ss;
  196. for (int i = 0; i < length; i++)
  197. ss << std::setw(2) << std::setfill('0') << std::hex << (int)bytes[i];
  198. return ss.str();
  199. }
  200. std::string keyToString(const key25519 key)
  201. {
  202. return hexArrayToString(key, KEYSIZE);
  203. }
  204. std::string hashToString(const uint8_t hash[crypto_hash_sha512_BYTES])
  205. {
  206. return hexArrayToString(hash, crypto_hash_sha512_BYTES);
  207. }
  208. void logKeys(uint8_t * raw, const key25519 publicKey, const key25519 privateKey)
  209. {
  210. if(newline) // добавляем пустую строку на экране между счетчиком и новым адресом
  211. {
  212. std::cout << std::endl;
  213. newline = false;
  214. }
  215. if (conf.mesh) {
  216. std::string mesh = getMeshname(raw);
  217. std::cout << " Domain: " << pickupMeshnameForOutput(mesh) << std::endl;
  218. }
  219. std::cout << " Address: " << getAddress(raw) << std::endl;
  220. std::cout << " PublicKey: " << keyToString(publicKey) << std::endl;
  221. std::cout << " PrivateKey: " << keyToString(privateKey) << std::endl;
  222. std::cout << std::endl;
  223. if (conf.log) // запись в файл
  224. {
  225. std::ofstream output(conf.outputfile, std::ios::app);
  226. output << std::endl;
  227. if (conf.mesh) {
  228. std::string mesh = getMeshname(raw);
  229. output << "Domain: " << pickupMeshnameForOutput(mesh) << std::endl;
  230. }
  231. output << "Address: " << getAddress(raw) << std::endl;
  232. output << "EncryptionPublicKey: " << keyToString(publicKey) << std::endl;
  233. output << "EncryptionPrivateKey: " << keyToString(privateKey) << std::endl;
  234. output.close();
  235. }
  236. }
  237. void process_fortune_key(const keys_block& block, int index)
  238. {
  239. if (index == -1)
  240. return;
  241. key25519 public_key;
  242. key25519 private_key;
  243. block.get_public_key(public_key, index);
  244. block.get_private_key(private_key, index);
  245. uint8_t sha512_hash[crypto_hash_sha512_BYTES];
  246. crypto_hash_sha512(sha512_hash, public_key);
  247. int ones = getOnes(sha512_hash);
  248. uint8_t raw[16];
  249. getRawAddress(ones, sha512_hash, raw);
  250. logKeys(raw, public_key, private_key);
  251. ++totalcountfortune;
  252. }
  253. template <int T>
  254. void miner_thread()
  255. {
  256. key25519 public_key;
  257. keys_block block(BLOCKSIZE);
  258. uint8_t random_bytes[KEYSIZE];
  259. uint8_t sha512_hash[crypto_hash_sha512_BYTES];
  260. if (T == 4 || T == 5) // meshname pattern
  261. {
  262. std::string tmp = pickupStringForMeshname(conf.str_search);
  263. conf.str_search = tmp;
  264. for (auto it = conf.rgx_search.begin(); it != conf.rgx_search.end(); it++)
  265. *it = toupper(*it);
  266. }
  267. std::regex regx(conf.rgx_search, std::regex_constants::egrep);
  268. if (T == 6) // subnet brute force
  269. {
  270. mtx.lock();
  271. if(!conf.sbt_alarm) // однократный вывод ошибки
  272. {
  273. subnetCheck();
  274. bool result = convertStrToRaw(conf.str_search, conf.raw_search);
  275. if(!result || (conf.str_search != getAddress(conf.raw_search)))
  276. {
  277. std::cerr << " WARNING: Your string [" << conf.str_search << "] converted to IP [" <<
  278. getAddress(conf.raw_search) << "]" << std::endl << std::endl;
  279. }
  280. conf.sbt_alarm = true;
  281. }
  282. mtx.unlock();
  283. }
  284. for (;;)
  285. {
  286. auto start_time = std::chrono::steady_clock::now();
  287. int fortune_key_index = -1;
  288. randombytes(random_bytes, KEYSIZE);
  289. block.calculate_public_keys(random_bytes);
  290. for (int i = 0; i < BLOCKSIZE; i++)
  291. {
  292. block.get_public_key(public_key, i);
  293. crypto_hash_sha512(sha512_hash, public_key);
  294. int newones = getOnes(sha512_hash);
  295. if (T == 0) // IPv6 pattern mining
  296. {
  297. uint8_t rawAddr[16];
  298. getRawAddress(newones, sha512_hash, rawAddr); // получаем адрес
  299. if (getAddress(rawAddr).find(
  300. conf.str_search.c_str()) != std::string::npos)
  301. {
  302. fortune_key_index = i;
  303. break;
  304. /* Можно использовать только один ключ из блока, т.к.
  305. * Vort, создавший используемую систему блоков ключей
  306. * с мутациями, посчитал, что использование двух адресов
  307. * из одного блока на разных серверах небезопасно:
  308. * при компрометации одного сервера, второй компьютер
  309. * этого администратора с мутированным ключом того же
  310. * блока также попадает под удар.
  311. * При поиске высокого адреса несколько другой подход:
  312. * блок не прерывается, т.к. с наибольшей вероятностью
  313. * администратором будет использован только последний,
  314. * самый высокий адрес из полученных.
  315. * @acetone
  316. */
  317. }
  318. }
  319. if (T == 1) // high mining
  320. {
  321. if (newones > conf.high)
  322. {
  323. conf.high = newones;
  324. fortune_key_index = i;
  325. }
  326. }
  327. if (T == 2) // pattern & high mining
  328. {
  329. uint8_t rawAddr[16];
  330. getRawAddress(newones, sha512_hash, rawAddr); // получаем адрес
  331. if (newones > conf.high && getAddress(rawAddr).find(
  332. conf.str_search.c_str()) != std::string::npos)
  333. {
  334. conf.high = newones;
  335. fortune_key_index = i;
  336. break;
  337. }
  338. }
  339. if (T == 3) // IPv6 regexp mining
  340. {
  341. uint8_t rawAddr[16];
  342. getRawAddress(newones, sha512_hash, rawAddr); // получаем адрес
  343. if (std::regex_search((getAddress(rawAddr)), regx))
  344. {
  345. fortune_key_index = i;
  346. break;
  347. }
  348. }
  349. if (T == 4) // meshname pattern mining
  350. {
  351. uint8_t rawAddr[16];
  352. getRawAddress(newones, sha512_hash, rawAddr); // получаем адрес
  353. if (getMeshname(rawAddr).find(
  354. conf.str_search.c_str()) != std::string::npos)
  355. {
  356. fortune_key_index = i;
  357. break;
  358. }
  359. }
  360. if (T == 5) // meshname regexp mining
  361. {
  362. uint8_t rawAddr[16];
  363. getRawAddress(newones, sha512_hash, rawAddr); // получаем адрес
  364. if (std::regex_search((getMeshname(rawAddr)), regx))
  365. {
  366. fortune_key_index = i;
  367. break;
  368. }
  369. }
  370. if (T == 6) // subnet brute force
  371. {
  372. uint8_t rawAddr[16];
  373. getRawAddress(newones, sha512_hash, rawAddr);
  374. for(int z = 0; conf.raw_search[z] == rawAddr[z]; ++z)
  375. {
  376. if (z == conf.sbt_size)
  377. fortune_key_index = i;
  378. }
  379. }
  380. }
  381. auto stop_time = std::chrono::steady_clock::now();
  382. mtx.lock();
  383. blocks_duration += stop_time - start_time;
  384. process_fortune_key(block, fortune_key_index);
  385. logStatistics();
  386. mtx.unlock();
  387. }
  388. }
  389. #ifdef SELF_CHECK // debug
  390. void selfCheck()
  391. {
  392. std::cout << "Self-check started." << std::endl;
  393. for (int i = 0; i < 16; i++)
  394. {
  395. int block_size = 1 << i;
  396. keys_block block(block_size);
  397. uint8_t random_bytes[KEYSIZE];
  398. randombytes(random_bytes, KEYSIZE);
  399. block.calculate_public_keys(random_bytes);
  400. key25519 public_key1;
  401. key25519 public_key2;
  402. key25519 private_key;
  403. uint8_t sha512_hash1[crypto_hash_sha512_BYTES];
  404. uint8_t sha512_hash2[crypto_hash_sha512_BYTES];
  405. for (int j = 0; j < block_size; j++)
  406. {
  407. block.get_public_key(public_key1, j);
  408. block.get_private_key(private_key, j);
  409. crypto_scalarmult_curve25519_base(public_key2, private_key);
  410. crypto_hash_sha512(sha512_hash1, public_key2);
  411. crypto_hash_sha512(sha512_hash2, public_key2, KEYSIZE);
  412. if (memcmp(public_key1, public_key2, KEYSIZE) != 0 ||
  413. memcmp(sha512_hash1, sha512_hash2, crypto_hash_sha512_BYTES))
  414. {
  415. std::cout << "!!! Self-check failed !!!" << std::endl;
  416. std::cout << " PrivateKey: " << keyToString(private_key) << std::endl;
  417. std::cout << " PublicKey1: " << keyToString(public_key1) << std::endl;
  418. std::cout << " PublicKey2: " << keyToString(public_key2) << std::endl;
  419. std::cout << " SHA512Hash1: " << hashToString(sha512_hash1) << std::endl;
  420. std::cout << " SHA512Hash2: " << hashToString(sha512_hash2) << std::endl;
  421. std::cout << "!!! Self-check failed !!!" << std::endl;
  422. return;
  423. }
  424. else
  425. {
  426. //std::cout << " Self-check ok" << std::endl;
  427. //std::cout << " PrivateKey: " << keyToString(private_key) << std::endl;
  428. }
  429. }
  430. }
  431. std::cout << "Self-check finished." << std::endl;
  432. }
  433. #endif // debug
  434. // ------------------------------------------------------
  435. void startThreads()
  436. {
  437. std::thread* lastThread;
  438. for (int i = 0; i < conf.proc; i++)
  439. {
  440. lastThread = new std::thread(
  441. conf.mode == 0 ? miner_thread<0> :
  442. conf.mode == 1 ? miner_thread<1> :
  443. conf.mode == 2 ? miner_thread<2> :
  444. conf.mode == 3 ? miner_thread<3> :
  445. conf.mode == 4 ? miner_thread<4> :
  446. conf.mode == 5 ? miner_thread<5> :
  447. miner_thread<6>
  448. );
  449. }
  450. lastThread->join();
  451. }
  452. void error()
  453. {
  454. std::cerr << std::endl <<
  455. " +--------------------------------------------------------------------------+\n" <<
  456. " | Incorrect input, my dear friend. Use -help or -h for usage information. |\n" <<
  457. " +--------------------------------------------------------------------------+\n";
  458. }
  459. void help()
  460. {
  461. std::cout << std::endl <<
  462. " +--------------------------------------------------------------------------+\n" <<
  463. " | Simple Yggdrasil address miner usage |\n" <<
  464. " +--------------------------------------------------------------------------+\n" <<
  465. " High addresses mining -high <start position> <threads count>\n" <<
  466. " example: -high 1f 1 (start position 21f:*, 1 thread)\n" <<
  467. " IPv6 pattern mining -ippattern <pattern> <threads count>\n" <<
  468. " example: -ippattern ace 2 (search \"ace\", 2 threads)\n" <<
  469. " IPv6 pattern & high mining -pahi <pattern> <start position> <threads count>\n" <<
  470. " example: -pahi ace 1a 4 (search \"ace\", start 21a:*, 4 threads)\n" <<
  471. " IPv6 regexp mining -ipreg \"<regexp>\" <threads count>\n" <<
  472. " example: -ipreg \"^20[10-15].*.:a$\" 16 (search, 16 threads)\n" <<
  473. " Meshname pattern mining -meshpattern <pattern> <threads count>\n" <<
  474. " example: -meshpattern acetone 8 (search \"acetone\", 8 threads)\n" <<
  475. " Meshname regexp mining -meshreg \"<regexp>\" <threads count>\n" <<
  476. " example: -meshreg \"^aimbot\" 1 (search, 1 thread)\n" <<
  477. " Subnet brute force mining -brute <IPv6> <threads count>\n" <<
  478. " example: -brute 300:b24b:: 4 (search subnet, 4 threads)\n" <<
  479. " +--------------------------------------------------------------------------+\n" <<
  480. " Convert IP to Meshname -tomesh <IPv6>\n" <<
  481. " Convert Meshname to IP -toip <domain>\n" <<
  482. " +--------------------------------------------------------------------------+\n" <<
  483. " [!] Meshname domains use base32 (RFC4648) alphabet symbols. \n" <<
  484. " [!] In meshname domain use \"=\" or \"===\" instead \".meshname\". \n" <<
  485. " [!] Subnet brute force mode understand \"3xx:\" and \"2xx:\" patterns. \n" <<
  486. " +--------------------------------------------------------------------------+\n" <<
  487. " ALSO YOU CAN USE CONFIGURATION FILE INSTEAD PASSED PARAMETERS. JUST RUN SYG.\n";
  488. }
  489. int main(int argc, char *argv[])
  490. {
  491. #ifdef SELF_CHECK
  492. selfCheck();
  493. return 0;
  494. #endif
  495. std::string p1;
  496. if(argv[1] != nullptr)
  497. {
  498. ///////////////////////////////// Доп. функции конвертации адресов
  499. p1 = argv[1];
  500. if (p1 == "-help" || p1 == "-h") {
  501. help();
  502. return 0;
  503. } else if (p1 == "-tomesh") { // преобразование IP -> Meshname
  504. if (argv[2] != nullptr) {
  505. convertStrToRaw(argv[2], conf.raw_search);
  506. std::string mesh = getMeshname(conf.raw_search);
  507. std::cout << std::endl <<
  508. pickupMeshnameForOutput(mesh) << std::endl;
  509. return 0;
  510. } else { error(); return -501; }
  511. } else if (p1 == "-toip") { // преобразование Meshname -> IP
  512. if (argv[2] != nullptr) {
  513. std::cout << std::endl <<
  514. decodeMeshToIP(argv[2]) << std::endl;
  515. return 0;
  516. } else { error(); return -502; }
  517. }
  518. ///////////////////////////////// Штатные функции
  519. else if (p1 == "-high") { // high mining
  520. if (argv[2] != nullptr && argv[3] != nullptr) {
  521. conf.mode = 1;
  522. std::istringstream ss(argv[2]);
  523. ss >> std::hex >> conf.high;
  524. conf.proc = std::stoi(argv[3]);
  525. Intro();
  526. DisplayConfig();
  527. testoutput();
  528. startThreads();
  529. } else { error(); return -503; }
  530. } else if (p1 == "-ippattern") { // IPv6 pattern mining
  531. if (argv[2] != nullptr && argv[3] != nullptr) {
  532. conf.mode = 0;
  533. conf.str_search = argv[2];
  534. conf.proc = std::stoi(argv[3]);
  535. Intro();
  536. DisplayConfig();
  537. testoutput();
  538. startThreads();
  539. } else { error(); return -504; }
  540. } else if (p1 == "-pahi") { // pattern & high mining
  541. if (argv[2] != nullptr && argv[3] != nullptr && argv[4] != nullptr) {
  542. conf.mode = 2;
  543. conf.str_search = argv[2];
  544. std::istringstream ss(argv[3]);
  545. ss >> std::hex >> conf.high;
  546. conf.proc = std::stoi(argv[4]);
  547. Intro();
  548. DisplayConfig();
  549. testoutput();
  550. startThreads();
  551. } else { error(); return -505; }
  552. } else if (p1 == "-ipreg") { // IPv6 regexp mining
  553. if (argv[2] != nullptr && argv[3] != nullptr) {
  554. conf.mode = 3;
  555. conf.rgx_search = argv[2];
  556. conf.proc = std::stoi(argv[3]);
  557. Intro();
  558. DisplayConfig();
  559. testoutput();
  560. startThreads();
  561. } else { error(); return -506; }
  562. } else if (p1 == "-meshpattern") { // meshname pattern mining
  563. if (argv[2] != nullptr && argv[3] != nullptr) {
  564. conf.mode = 4;
  565. conf.str_search = argv[2];
  566. conf.proc = std::stoi(argv[3]);
  567. Intro();
  568. DisplayConfig();
  569. testoutput();
  570. startThreads();
  571. } else { error(); return -507; }
  572. } else if (p1 == "-meshreg") { // meshname regexp mining
  573. if (argv[2] != nullptr && argv[3] != nullptr) {
  574. conf.mode = 5;
  575. conf.rgx_search = argv[2];
  576. conf.proc = std::stoi(argv[3]);
  577. Intro();
  578. DisplayConfig();
  579. testoutput();
  580. startThreads();
  581. } else { error(); return -508; }
  582. } else if (p1 == "-brute") { // subnet brute force
  583. if (argv[2] != nullptr && argv[3] != nullptr) {
  584. conf.mode = 6;
  585. conf.str_search = argv[2];
  586. conf.proc = std::stoi(argv[3]);
  587. Intro();
  588. DisplayConfig();
  589. testoutput();
  590. startThreads();
  591. } else { error(); return -509; }
  592. } else {error(); return -510;} // Первый параметр - неверный
  593. } else { // Запуск без параметров, работа с конфигом
  594. Intro();
  595. int configcheck = config(); // функция получения конфигурации
  596. if(configcheck < 0)
  597. {
  598. std::cerr << " Error code: " << configcheck;
  599. std::this_thread::sleep_for(std::chrono::seconds(15));
  600. return configcheck;
  601. }
  602. DisplayConfig();
  603. testoutput();
  604. startThreads();
  605. }
  606. std::cerr << "SYG has stopped working unexpectedly! Please, report about this.";
  607. std::this_thread::sleep_for(std::chrono::seconds(15));
  608. return -420;
  609. }