snifftest.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. /* snifftest.c
  2. *
  3. * Copyright (C) 2006-2020 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #include <wolfssl/wolfcrypt/types.h>
  26. #include <wolfssl/wolfcrypt/logging.h>
  27. #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
  28. #include <wolfssl/wolfcrypt/memory.h>
  29. #endif
  30. #ifdef _WIN32
  31. #define WOLFSSL_SNIFFER
  32. #endif
  33. #ifndef WOLFSSL_SNIFFER
  34. #ifndef NO_MAIN_DRIVER
  35. /* blank build */
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. int main(void)
  39. {
  40. printf("do ./configure --enable-sniffer to enable build support\n");
  41. return EXIT_SUCCESS;
  42. }
  43. #endif /* !NO_MAIN_DRIVER */
  44. #else
  45. /* do a full build */
  46. #ifdef _MSC_VER
  47. /* builds on *nix too, for scanf device and port */
  48. #define _CRT_SECURE_NO_WARNINGS
  49. #endif
  50. #include <pcap/pcap.h> /* pcap stuff */
  51. #include <stdio.h> /* printf */
  52. #include <stdlib.h> /* EXIT_SUCCESS */
  53. #include <string.h> /* strcmp */
  54. #include <signal.h> /* signal */
  55. #include <ctype.h> /* isprint */
  56. #include <cyassl/sniffer.h>
  57. #ifndef _WIN32
  58. #include <sys/socket.h> /* AF_INET */
  59. #include <arpa/inet.h>
  60. #include <netinet/in.h>
  61. #endif
  62. typedef unsigned char byte;
  63. enum {
  64. ETHER_IF_FRAME_LEN = 14, /* ethernet interface frame length */
  65. NULL_IF_FRAME_LEN = 4, /* no link interface frame length */
  66. };
  67. /* A TLS record can be 16k and change. The chain is broken up into 2K chunks.
  68. * This covers the TLS record, plus a chunk for TCP/IP headers. */
  69. #ifndef CHAIN_INPUT_CHUNK_SIZE
  70. #define CHAIN_INPUT_CHUNK_SIZE 2048
  71. #elif (CHAIN_INPUT_CHUNK_SIZE < 256)
  72. #undef CHAIN_INPUT_CHUNK_SIZE
  73. #define CHAIN_INPUT_CHUNK_SIZE 256
  74. #elif (CHAIN_INPUT_CHUNK_SIZE > 16384)
  75. #undef CHAIN_INPUT_CHUNK_SIZE
  76. #define CHAIN_INPUT_CHUNK_SIZE 16384
  77. #endif
  78. #define CHAIN_INPUT_COUNT ((16384 / CHAIN_INPUT_CHUNK_SIZE) + 1)
  79. #ifndef STORE_DATA_BLOCK_SZ
  80. #define STORE_DATA_BLOCK_SZ 1024
  81. #endif
  82. #define DEFAULT_SERVER_EPH_KEY_ECC "../../certs/statickeys/ecc-secp256r1.pem"
  83. #define DEFAULT_SERVER_EPH_KEY_DH "../../certs/statickeys/dh-ffdhe2048.pem"
  84. #ifndef DEFAULT_SERVER_EPH_KEY
  85. #if defined(HAVE_ECC) && !defined(NO_ECC_SECP) && \
  86. (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES))
  87. #if !defined(NO_DH)
  88. #define DEFAULT_SERVER_EPH_KEY DEFAULT_SERVER_EPH_KEY_ECC "," DEFAULT_SERVER_EPH_KEY_DH
  89. #else
  90. #define DEFAULT_SERVER_EPH_KEY DEFAULT_SERVER_EPH_KEY_ECC
  91. #endif
  92. #elif !defined(NO_DH)
  93. #define DEFAULT_SERVER_EPH_KEY DEFAULT_SERVER_EPH_KEY_DH
  94. #endif
  95. #endif
  96. #define DEFAULT_SERVER_KEY_RSA "../../certs/server-key.pem"
  97. #define DEFAULT_SERVER_KEY_ECC "../../certs/ecc-key.pem"
  98. #ifndef DEFAULT_SERVER_KEY
  99. #ifndef NO_RSA
  100. #define DEFAULT_SERVER_KEY DEFAULT_SERVER_KEY_RSA
  101. #elif defined(HAVE_ECC)
  102. #define DEFAULT_SERVER_KEY DEFAULT_SERVER_KEY_ECC
  103. #endif
  104. #endif
  105. #ifdef WOLFSSL_SNIFFER_WATCH
  106. static const byte rsaHash[] = {
  107. 0x4e, 0xa8, 0x55, 0x02, 0xe1, 0x84, 0x7e, 0xe1,
  108. 0xb5, 0x97, 0xd2, 0xf0, 0x92, 0x3a, 0xfd, 0x0d,
  109. 0x98, 0x26, 0x06, 0x85, 0x8d, 0xa4, 0xc7, 0x35,
  110. 0xd4, 0x74, 0x8f, 0xd0, 0xe7, 0xa8, 0x27, 0xaa
  111. };
  112. static const byte eccHash[] = {
  113. 0x80, 0x3d, 0xff, 0xca, 0x2e, 0x20, 0xd9, 0xdf,
  114. 0xfe, 0x64, 0x4e, 0x25, 0x6a, 0xee, 0xee, 0x60,
  115. 0xc1, 0x48, 0x7b, 0xff, 0xa0, 0xfb, 0xeb, 0xac,
  116. 0xe2, 0xa4, 0xdd, 0xb5, 0x18, 0x38, 0x78, 0x38
  117. };
  118. #endif
  119. pcap_t* pcap = NULL;
  120. pcap_if_t* alldevs = NULL;
  121. static void FreeAll(void)
  122. {
  123. if (pcap)
  124. pcap_close(pcap);
  125. if (alldevs)
  126. pcap_freealldevs(alldevs);
  127. #ifndef _WIN32
  128. ssl_FreeSniffer();
  129. #endif
  130. }
  131. #ifdef WOLFSSL_SNIFFER_STATS
  132. static void DumpStats(void)
  133. {
  134. SSLStats sslStats;
  135. ssl_ReadStatistics(&sslStats);
  136. printf("SSL Stats (sslStandardConns):%lu\n",
  137. sslStats.sslStandardConns);
  138. printf("SSL Stats (sslClientAuthConns):%lu\n",
  139. sslStats.sslClientAuthConns);
  140. printf("SSL Stats (sslResumedConns):%lu\n",
  141. sslStats.sslResumedConns);
  142. printf("SSL Stats (sslEphemeralMisses):%lu\n",
  143. sslStats.sslEphemeralMisses);
  144. printf("SSL Stats (sslResumeMisses):%lu\n",
  145. sslStats.sslResumeMisses);
  146. printf("SSL Stats (sslCiphersUnsupported):%lu\n",
  147. sslStats.sslCiphersUnsupported);
  148. printf("SSL Stats (sslKeysUnmatched):%lu\n",
  149. sslStats.sslKeysUnmatched);
  150. printf("SSL Stats (sslKeyFails):%lu\n",
  151. sslStats.sslKeyFails);
  152. printf("SSL Stats (sslDecodeFails):%lu\n",
  153. sslStats.sslDecodeFails);
  154. printf("SSL Stats (sslAlerts):%lu\n",
  155. sslStats.sslAlerts);
  156. printf("SSL Stats (sslDecryptedBytes):%lu\n",
  157. sslStats.sslDecryptedBytes);
  158. printf("SSL Stats (sslEncryptedBytes):%lu\n",
  159. sslStats.sslEncryptedBytes);
  160. printf("SSL Stats (sslEncryptedPackets):%lu\n",
  161. sslStats.sslEncryptedPackets);
  162. printf("SSL Stats (sslDecryptedPackets):%lu\n",
  163. sslStats.sslDecryptedPackets);
  164. printf("SSL Stats (sslKeyMatches):%lu\n",
  165. sslStats.sslKeyMatches);
  166. printf("SSL Stats (sslEncryptedConns):%lu\n",
  167. sslStats.sslEncryptedConns);
  168. }
  169. #endif /* WOLFSSL_SNIFFER_STATS */
  170. static void sig_handler(const int sig)
  171. {
  172. printf("SIGINT handled = %d.\n", sig);
  173. FreeAll();
  174. #ifdef WOLFSSL_SNIFFER_STATS
  175. DumpStats();
  176. #endif
  177. if (sig)
  178. exit(EXIT_SUCCESS);
  179. }
  180. static void err_sys(const char* msg)
  181. {
  182. fprintf(stderr, "%s\n", msg);
  183. if (msg)
  184. exit(EXIT_FAILURE);
  185. }
  186. #ifdef _WIN32
  187. #define SNPRINTF _snprintf
  188. #else
  189. #define SNPRINTF snprintf
  190. #endif
  191. static char* iptos(const struct in_addr* addr)
  192. {
  193. static char output[32];
  194. byte *p = (byte*)&addr->s_addr;
  195. snprintf(output, sizeof(output), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  196. return output;
  197. }
  198. static const char* ip6tos(const struct in6_addr* addr)
  199. {
  200. static char output[42];
  201. return inet_ntop(AF_INET6, addr, output, 42);
  202. }
  203. #if defined(WOLFSSL_SNIFFER_STORE_DATA_CB) || defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
  204. static inline unsigned int min(unsigned int a, unsigned int b)
  205. {
  206. return a > b ? b : a;
  207. }
  208. #endif
  209. #ifdef WOLFSSL_SNIFFER_WATCH
  210. static int myWatchCb(void* vSniffer,
  211. const unsigned char* certHash, unsigned int certHashSz,
  212. const unsigned char* certChain, unsigned int certChainSz,
  213. void* ctx, char* error)
  214. {
  215. const char* certName = NULL;
  216. (void)certChain;
  217. (void)certChainSz;
  218. (void)ctx;
  219. if (certHashSz == sizeof(rsaHash) &&
  220. XMEMCMP(certHash, rsaHash, certHashSz) == 0) {
  221. certName = DEFAULT_SERVER_KEY_RSA;
  222. }
  223. if (certHashSz == sizeof(eccHash) &&
  224. XMEMCMP(certHash, eccHash, certHashSz) == 0) {
  225. certName = DEFAULT_SERVER_KEY_ECC;
  226. }
  227. if (certName == NULL) {
  228. /* don't return error if key is not loaded */
  229. printf("Warning: No matching key found for cert hash\n");
  230. return 0;
  231. }
  232. return ssl_SetWatchKey_file(vSniffer, certName, FILETYPE_PEM, NULL, error);
  233. }
  234. #endif /* WOLFSSL_SNIFFER_WATCH */
  235. #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
  236. static int myStoreDataCb(const unsigned char* decryptBuf,
  237. unsigned int decryptBufSz, unsigned int decryptBufOffset, void* ctx)
  238. {
  239. byte** data = (byte**)ctx;
  240. unsigned int qty;
  241. if (data == NULL)
  242. return -1;
  243. if (decryptBufSz < decryptBufOffset)
  244. return -1;
  245. qty = min(decryptBufSz - decryptBufOffset, STORE_DATA_BLOCK_SZ);
  246. if (*data == NULL) {
  247. byte* tmpData;
  248. tmpData = (byte*)XREALLOC(*data, decryptBufSz + 1,
  249. NULL, DYNAMIC_TYPE_TMP_BUFFER);
  250. if (tmpData == NULL) {
  251. XFREE(*data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  252. *data = NULL;
  253. return -1;
  254. }
  255. *data = tmpData;
  256. }
  257. XMEMCPY(*data + decryptBufOffset, decryptBuf + decryptBufOffset, qty);
  258. return qty;
  259. }
  260. #endif /* WOLFSSL_SNIFFER_STORE_DATA_CB */
  261. /* try and load as both static ephemeral and private key */
  262. /* only fail if no key is loaded */
  263. /* Allow comma seperated list of files */
  264. static int load_key(const char* name, const char* server, int port,
  265. const char* keyFiles, const char* passwd, char* err)
  266. {
  267. int ret = -1;
  268. int loadCount = 0;
  269. char *keyFile, *ptr = NULL;
  270. keyFile = XSTRTOK((char*)keyFiles, ",", &ptr);
  271. while (keyFile != NULL) {
  272. #ifdef WOLFSSL_STATIC_EPHEMERAL
  273. #ifdef HAVE_SNI
  274. ret = ssl_SetNamedEphemeralKey(name, server, port, keyFile,
  275. FILETYPE_PEM, passwd, err);
  276. #else
  277. ret = ssl_SetEphemeralKey(server, port, keyFile,
  278. FILETYPE_PEM, passwd, err);
  279. #endif
  280. if (ret == 0)
  281. loadCount++;
  282. #endif
  283. #ifdef HAVE_SNI
  284. ret = ssl_SetNamedPrivateKey(name, server, port, keyFile,
  285. FILETYPE_PEM, passwd, err);
  286. #else
  287. ret = ssl_SetPrivateKey(server, port, keyFile,
  288. FILETYPE_PEM, passwd, err);
  289. #endif
  290. if (ret == 0)
  291. loadCount++;
  292. if (loadCount == 0) {
  293. printf("Failed loading private key %s: ret %d\n", keyFile, ret);
  294. printf("Please run directly from sslSniffer/sslSnifferTest dir\n");
  295. ret = -1;
  296. }
  297. else {
  298. ret = 0;
  299. }
  300. keyFile = XSTRTOK(NULL, ",", &ptr);
  301. }
  302. (void)name;
  303. return ret;
  304. }
  305. int main(int argc, char** argv)
  306. {
  307. int ret = 0;
  308. int hadBadPacket = 0;
  309. int inum = 0;
  310. int port = 0;
  311. int saveFile = 0;
  312. int i = 0, defDev = 0;
  313. int frame = ETHER_IF_FRAME_LEN;
  314. char err[PCAP_ERRBUF_SIZE];
  315. char filter[32];
  316. const char *keyFilesSrc = NULL;
  317. char keyFilesBuf[MAX_FILENAME_SZ];
  318. char keyFilesUser[MAX_FILENAME_SZ];
  319. const char *server = NULL;
  320. const char *sniName = NULL;
  321. struct bpf_program fp;
  322. pcap_if_t *d;
  323. pcap_addr_t *a;
  324. #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
  325. struct iovec chain[CHAIN_INPUT_COUNT];
  326. int chainSz;
  327. #endif
  328. signal(SIGINT, sig_handler);
  329. #ifndef _WIN32
  330. ssl_InitSniffer(); /* dll load on Windows */
  331. #endif
  332. #ifdef DEBUG_WOLFSSL
  333. //wolfSSL_Debugging_ON();
  334. #endif
  335. ssl_Trace("./tracefile.txt", err);
  336. ssl_EnableRecovery(1, -1, err);
  337. #ifdef WOLFSSL_SNIFFER_WATCH
  338. ssl_SetWatchKeyCallback(myWatchCb, err);
  339. #endif
  340. #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
  341. ssl_SetStoreDataCallback(myStoreDataCb);
  342. #endif
  343. if (argc == 1) {
  344. char cmdLineArg[128];
  345. /* normal case, user chooses device and port */
  346. if (pcap_findalldevs(&alldevs, err) == -1)
  347. err_sys("Error in pcap_findalldevs");
  348. for (d = alldevs; d; d=d->next) {
  349. printf("%d. %s", ++i, d->name);
  350. if (strcmp(d->name, "lo0") == 0) {
  351. defDev = i;
  352. }
  353. if (d->description)
  354. printf(" (%s)\n", d->description);
  355. else
  356. printf(" (No description available)\n");
  357. }
  358. if (i == 0)
  359. err_sys("No interfaces found! Make sure pcap or WinPcap is"
  360. " installed correctly and you have sufficient permissions");
  361. printf("Enter the interface number (1-%d) [default: %d]: ", i, defDev);
  362. XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
  363. if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin))
  364. inum = XATOI(cmdLineArg);
  365. if (inum == 0)
  366. inum = defDev;
  367. else if (inum < 1 || inum > i)
  368. err_sys("Interface number out of range");
  369. /* Jump to the selected adapter */
  370. for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
  371. pcap = pcap_create(d->name, err);
  372. if (pcap == NULL) printf("pcap_create failed %s\n", err);
  373. /* print out addresses for selected interface */
  374. for (a = d->addresses; a; a = a->next) {
  375. if (a->addr->sa_family == AF_INET) {
  376. server =
  377. iptos(&((struct sockaddr_in *)a->addr)->sin_addr);
  378. printf("server = %s\n", server);
  379. }
  380. else if (a->addr->sa_family == AF_INET6) {
  381. server =
  382. ip6tos(&((struct sockaddr_in6 *)a->addr)->sin6_addr);
  383. printf("server = %s\n", server);
  384. }
  385. }
  386. if (server == NULL)
  387. err_sys("Unable to get device IPv4 or IPv6 address");
  388. ret = pcap_set_snaplen(pcap, 65536);
  389. if (ret != 0) printf("pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
  390. ret = pcap_set_timeout(pcap, 1000);
  391. if (ret != 0) printf("pcap_set_timeout failed %s\n", pcap_geterr(pcap));
  392. ret = pcap_set_buffer_size(pcap, 1000000);
  393. if (ret != 0)
  394. printf("pcap_set_buffer_size failed %s\n", pcap_geterr(pcap));
  395. ret = pcap_set_promisc(pcap, 1);
  396. if (ret != 0) printf("pcap_set_promisc failed %s\n", pcap_geterr(pcap));
  397. ret = pcap_activate(pcap);
  398. if (ret != 0) printf("pcap_activate failed %s\n", pcap_geterr(pcap));
  399. printf("Enter the port to scan [default: 11111]: ");
  400. XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
  401. if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin)) {
  402. port = XATOI(cmdLineArg);
  403. }
  404. if (port <= 0)
  405. port = 11111;
  406. SNPRINTF(filter, sizeof(filter), "tcp and port %d", port);
  407. ret = pcap_compile(pcap, &fp, filter, 0, 0);
  408. if (ret != 0) printf("pcap_compile failed %s\n", pcap_geterr(pcap));
  409. ret = pcap_setfilter(pcap, &fp);
  410. if (ret != 0) printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
  411. /* optionally enter the private key to use */
  412. #if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(DEFAULT_SERVER_EPH_KEY)
  413. keyFilesSrc = DEFAULT_SERVER_EPH_KEY;
  414. #else
  415. keyFilesSrc = DEFAULT_SERVER_KEY;
  416. #endif
  417. printf("Enter the server key [default: %s]: ", keyFilesSrc);
  418. XMEMSET(keyFilesBuf, 0, sizeof(keyFilesBuf));
  419. XMEMSET(keyFilesUser, 0, sizeof(keyFilesUser));
  420. if (XFGETS(keyFilesUser, sizeof(keyFilesUser), stdin)) {
  421. word32 strSz;
  422. if (keyFilesUser[0] != '\r' && keyFilesUser[0] != '\n') {
  423. keyFilesSrc = keyFilesUser;
  424. }
  425. strSz = (word32)XSTRLEN(keyFilesUser);
  426. if (keyFilesUser[strSz-1] == '\n')
  427. keyFilesUser[strSz-1] = '\0';
  428. }
  429. XSTRNCPY(keyFilesBuf, keyFilesSrc, sizeof(keyFilesBuf));
  430. /* optionally enter a named key (SNI) */
  431. #if !defined(WOLFSSL_SNIFFER_WATCH) && defined(HAVE_SNI)
  432. printf("Enter alternate SNI [default: none]: ");
  433. XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
  434. if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin)) {
  435. if (XSTRLEN(cmdLineArg) > 0) {
  436. sniName = cmdLineArg;
  437. }
  438. }
  439. #endif /* !WOLFSSL_SNIFFER_WATCH && HAVE_SNI */
  440. /* get IPv4 or IPv6 addresses for selected interface */
  441. for (a = d->addresses; a; a = a->next) {
  442. server = NULL;
  443. if (a->addr->sa_family == AF_INET) {
  444. server =
  445. iptos(&((struct sockaddr_in *)a->addr)->sin_addr);
  446. }
  447. else if (a->addr->sa_family == AF_INET6) {
  448. server =
  449. ip6tos(&((struct sockaddr_in6 *)a->addr)->sin6_addr);
  450. }
  451. if (server) {
  452. XSTRNCPY(keyFilesBuf, keyFilesSrc, sizeof(keyFilesBuf));
  453. ret = load_key(sniName, server, port, keyFilesBuf, NULL, err);
  454. if (ret != 0) {
  455. exit(EXIT_FAILURE);
  456. }
  457. }
  458. }
  459. }
  460. else if (argc >= 3) {
  461. saveFile = 1;
  462. pcap = pcap_open_offline(argv[1], err);
  463. if (pcap == NULL) {
  464. printf("pcap_open_offline failed %s\n", err);
  465. ret = -1;
  466. }
  467. else {
  468. const char* passwd = NULL;
  469. /* defaults for server and port */
  470. port = 443;
  471. server = "127.0.0.1";
  472. keyFilesSrc = argv[2];
  473. if (argc >= 4)
  474. server = argv[3];
  475. if (argc >= 5)
  476. port = XATOI(argv[4]);
  477. if (argc >= 6)
  478. passwd = argv[5];
  479. ret = load_key(NULL, server, port, keyFilesSrc, passwd, err);
  480. if (ret != 0) {
  481. exit(EXIT_FAILURE);
  482. }
  483. /* Only let through TCP/IP packets */
  484. ret = pcap_compile(pcap, &fp, "(ip6 or ip) and tcp", 0, 0);
  485. if (ret != 0) {
  486. printf("pcap_compile failed %s\n", pcap_geterr(pcap));
  487. exit(EXIT_FAILURE);
  488. }
  489. ret = pcap_setfilter(pcap, &fp);
  490. if (ret != 0) {
  491. printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
  492. exit(EXIT_FAILURE);
  493. }
  494. }
  495. }
  496. else {
  497. /* usage error */
  498. printf( "usage: ./snifftest or ./snifftest dump pemKey"
  499. " [server] [port] [password]\n");
  500. exit(EXIT_FAILURE);
  501. }
  502. if (ret != 0)
  503. err_sys(err);
  504. if (pcap_datalink(pcap) == DLT_NULL)
  505. frame = NULL_IF_FRAME_LEN;
  506. while (1) {
  507. static int packetNumber = 0;
  508. struct pcap_pkthdr header;
  509. const unsigned char* packet = pcap_next(pcap, &header);
  510. SSLInfo sslInfo;
  511. packetNumber++;
  512. if (packet) {
  513. byte* data = NULL;
  514. if (header.caplen > 40) { /* min ip(20) + min tcp(20) */
  515. packet += frame;
  516. header.caplen -= frame;
  517. }
  518. else
  519. continue;
  520. #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
  521. {
  522. unsigned int j = 0;
  523. unsigned int remainder = header.caplen;
  524. chainSz = 0;
  525. do {
  526. unsigned int chunkSz;
  527. chunkSz = min(remainder, CHAIN_INPUT_CHUNK_SIZE);
  528. chain[chainSz].iov_base = (void*)(packet + j);
  529. chain[chainSz].iov_len = chunkSz;
  530. j += chunkSz;
  531. remainder -= chunkSz;
  532. chainSz++;
  533. } while (j < header.caplen);
  534. }
  535. #endif
  536. #if defined(WOLFSSL_SNIFFER_CHAIN_INPUT) && \
  537. defined(WOLFSSL_SNIFFER_STORE_DATA_CB)
  538. ret = ssl_DecodePacketWithChainSessionInfoStoreData(chain, chainSz,
  539. &data, &sslInfo, err);
  540. #elif defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
  541. (void)sslInfo;
  542. ret = ssl_DecodePacketWithChain(chain, chainSz, &data, err);
  543. #elif defined(WOLFSSL_SNIFFER_STORE_DATA_CB)
  544. ret = ssl_DecodePacketWithSessionInfoStoreData(packet,
  545. header.caplen, &data, &sslInfo, err);
  546. #else
  547. ret = ssl_DecodePacketWithSessionInfo(packet, header.caplen, &data,
  548. &sslInfo, err);
  549. #endif
  550. if (ret < 0) {
  551. printf("ssl_Decode ret = %d, %s\n", ret, err);
  552. hadBadPacket = 1;
  553. }
  554. if (ret > 0) {
  555. int j;
  556. /* Convert non-printable data to periods. */
  557. for (j = 0; j < ret; j++) {
  558. if (isprint(data[j]) || isspace(data[j])) continue;
  559. data[j] = '.';
  560. }
  561. data[ret] = 0;
  562. printf("SSL App Data(%d:%d):%s\n", packetNumber, ret, data);
  563. ssl_FreeZeroDecodeBuffer(&data, ret, err);
  564. }
  565. }
  566. else if (saveFile)
  567. break; /* we're done reading file */
  568. }
  569. FreeAll();
  570. return hadBadPacket ? EXIT_FAILURE : EXIT_SUCCESS;
  571. }
  572. #endif /* full build */