1 /* snifftest.c
2 *
3 * Copyright (C) 2006-2021 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
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <wolfssl/wolfcrypt/settings.h>
28 #include <wolfssl/wolfcrypt/types.h>
29 #include <wolfssl/wolfcrypt/logging.h>
30
31 #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
32 #include <wolfssl/wolfcrypt/memory.h>
33 #endif
34
35 #ifdef _WIN32
36 #define WOLFSSL_SNIFFER
37 #endif
38
39 #ifndef WOLFSSL_SNIFFER
40 #ifndef NO_MAIN_DRIVER
41 /* blank build */
42 #include <stdio.h>
43 #include <stdlib.h>
main(void)44 int main(void)
45 {
46 printf("do ./configure --enable-sniffer to enable build support\n");
47 return EXIT_SUCCESS;
48 }
49 #endif /* !NO_MAIN_DRIVER */
50 #else
51 /* do a full build */
52
53 #ifdef _MSC_VER
54 /* builds on *nix too, for scanf device and port */
55 #define _CRT_SECURE_NO_WARNINGS
56 #endif
57
58 #include <pcap/pcap.h> /* pcap stuff */
59 #include <stdio.h> /* printf */
60 #include <stdlib.h> /* EXIT_SUCCESS */
61 #include <string.h> /* strcmp */
62 #include <signal.h> /* signal */
63 #include <ctype.h> /* isprint */
64
65 #include <cyassl/sniffer.h>
66
67
68 #ifndef _WIN32
69 #include <sys/socket.h> /* AF_INET */
70 #include <arpa/inet.h>
71 #include <netinet/in.h>
72 #endif
73
74 typedef unsigned char byte;
75
76 enum {
77 ETHER_IF_FRAME_LEN = 14, /* ethernet interface frame length */
78 NULL_IF_FRAME_LEN = 4, /* no link interface frame length */
79 };
80
81
82 /* A TLS record can be 16k and change. The chain is broken up into 2K chunks.
83 * This covers the TLS record, plus a chunk for TCP/IP headers. */
84 #ifndef CHAIN_INPUT_CHUNK_SIZE
85 #define CHAIN_INPUT_CHUNK_SIZE 2048
86 #elif (CHAIN_INPUT_CHUNK_SIZE < 256)
87 #undef CHAIN_INPUT_CHUNK_SIZE
88 #define CHAIN_INPUT_CHUNK_SIZE 256
89 #elif (CHAIN_INPUT_CHUNK_SIZE > 16384)
90 #undef CHAIN_INPUT_CHUNK_SIZE
91 #define CHAIN_INPUT_CHUNK_SIZE 16384
92 #endif
93 #define CHAIN_INPUT_COUNT ((16384 / CHAIN_INPUT_CHUNK_SIZE) + 1)
94
95
96 #ifndef STORE_DATA_BLOCK_SZ
97 #define STORE_DATA_BLOCK_SZ 1024
98 #endif
99
100 #if defined(HAVE_ECC) && !defined(NO_ECC_SECP) && (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES))
101 #define DEFAULT_SERVER_EPH_KEY_ECC "../../certs/statickeys/ecc-secp256r1.pem"
102 #else
103 #define DEFAULT_SERVER_EPH_KEY_ECC ""
104 #endif
105 #ifndef NO_DH
106 #define DEFAULT_SERVER_EPH_KEY_DH "../../certs/statickeys/dh-ffdhe2048.pem"
107 #else
108 #define DEFAULT_SERVER_EPH_KEY_DH ""
109 #endif
110 #ifdef HAVE_CURVE25519
111 #define DEFAULT_SERVER_EPH_KEY_X25519 "../../certs/statickeys/x25519.pem"
112 #else
113 #define DEFAULT_SERVER_EPH_KEY_X25519 ""
114 #endif
115
116 #ifndef DEFAULT_SERVER_EPH_KEY
117 #define DEFAULT_SERVER_EPH_KEY \
118 DEFAULT_SERVER_EPH_KEY_ECC "," \
119 DEFAULT_SERVER_EPH_KEY_DH "," \
120 DEFAULT_SERVER_EPH_KEY_X25519
121 #endif
122
123 #define DEFAULT_SERVER_KEY_RSA "../../certs/server-key.pem"
124 #define DEFAULT_SERVER_KEY_ECC "../../certs/ecc-key.pem"
125 #ifndef DEFAULT_SERVER_KEY
126 #ifndef NO_RSA
127 #define DEFAULT_SERVER_KEY DEFAULT_SERVER_KEY_RSA
128 #elif defined(HAVE_ECC)
129 #define DEFAULT_SERVER_KEY DEFAULT_SERVER_KEY_ECC
130 #endif
131 #endif
132
133
134 #ifdef WOLFSSL_SNIFFER_WATCH
135 static const byte rsaHash[] = {
136 0x3d, 0x4a, 0x60, 0xfc, 0xbf, 0xe5, 0x4d, 0x3e,
137 0x85, 0x62, 0xf2, 0xfc, 0xdb, 0x0d, 0x51, 0xdd,
138 0xcd, 0xc2, 0x53, 0x81, 0x1a, 0x67, 0x31, 0xa0,
139 0x7f, 0xd2, 0x11, 0x74, 0xbf, 0xea, 0xc9, 0xc5
140 };
141 static const byte eccHash[] = {
142 0x9e, 0x45, 0xb6, 0xf8, 0xc6, 0x5d, 0x60, 0x90,
143 0x40, 0x8f, 0xd2, 0x0e, 0xb1, 0x59, 0xe7, 0xbd,
144 0xb0, 0x9b, 0x3c, 0x7a, 0x3a, 0xbe, 0x13, 0x52,
145 0x07, 0x4f, 0x1a, 0x64, 0x45, 0xe0, 0x13, 0x34
146 };
147 #endif
148
149
150 pcap_t* pcap = NULL;
151 pcap_if_t* alldevs = NULL;
152
153
FreeAll(void)154 static void FreeAll(void)
155 {
156 if (pcap)
157 pcap_close(pcap);
158 if (alldevs)
159 pcap_freealldevs(alldevs);
160 #ifndef _WIN32
161 ssl_FreeSniffer();
162 #endif
163 }
164
165
166 #ifdef WOLFSSL_SNIFFER_STATS
DumpStats(void)167 static void DumpStats(void)
168 {
169 SSLStats sslStats;
170 ssl_ReadStatistics(&sslStats);
171
172 printf("SSL Stats (sslStandardConns):%lu\n",
173 sslStats.sslStandardConns);
174 printf("SSL Stats (sslClientAuthConns):%lu\n",
175 sslStats.sslClientAuthConns);
176 printf("SSL Stats (sslResumedConns):%lu\n",
177 sslStats.sslResumedConns);
178 printf("SSL Stats (sslEphemeralMisses):%lu\n",
179 sslStats.sslEphemeralMisses);
180 printf("SSL Stats (sslResumptionInserts):%lu\n",
181 sslStats.sslResumptionInserts);
182 printf("SSL Stats (sslResumeMisses):%lu\n",
183 sslStats.sslResumeMisses);
184 printf("SSL Stats (sslCiphersUnsupported):%lu\n",
185 sslStats.sslCiphersUnsupported);
186 printf("SSL Stats (sslKeysUnmatched):%lu\n",
187 sslStats.sslKeysUnmatched);
188 printf("SSL Stats (sslKeyFails):%lu\n",
189 sslStats.sslKeyFails);
190 printf("SSL Stats (sslDecodeFails):%lu\n",
191 sslStats.sslDecodeFails);
192 printf("SSL Stats (sslAlerts):%lu\n",
193 sslStats.sslAlerts);
194 printf("SSL Stats (sslDecryptedBytes):%lu\n",
195 sslStats.sslDecryptedBytes);
196 printf("SSL Stats (sslEncryptedBytes):%lu\n",
197 sslStats.sslEncryptedBytes);
198 printf("SSL Stats (sslEncryptedPackets):%lu\n",
199 sslStats.sslEncryptedPackets);
200 printf("SSL Stats (sslDecryptedPackets):%lu\n",
201 sslStats.sslDecryptedPackets);
202 printf("SSL Stats (sslKeyMatches):%lu\n",
203 sslStats.sslKeyMatches);
204 printf("SSL Stats (sslEncryptedConns):%lu\n",
205 sslStats.sslEncryptedConns);
206 }
207 #endif /* WOLFSSL_SNIFFER_STATS */
208
209
sig_handler(const int sig)210 static void sig_handler(const int sig)
211 {
212 printf("SIGINT handled = %d.\n", sig);
213 FreeAll();
214 #ifdef WOLFSSL_SNIFFER_STATS
215 DumpStats();
216 #endif
217 if (sig)
218 exit(EXIT_SUCCESS);
219 }
220
221
err_sys(const char * msg)222 static void err_sys(const char* msg)
223 {
224 fprintf(stderr, "%s\n", msg);
225 if (msg)
226 exit(EXIT_FAILURE);
227 }
228
229
230 #ifdef _WIN32
231 #define SNPRINTF _snprintf
232 #else
233 #define SNPRINTF snprintf
234 #endif
235
236
iptos(const struct in_addr * addr)237 static char* iptos(const struct in_addr* addr)
238 {
239 static char output[32];
240 byte *p = (byte*)&addr->s_addr;
241
242 snprintf(output, sizeof(output), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
243
244 return output;
245 }
246
ip6tos(const struct in6_addr * addr)247 static const char* ip6tos(const struct in6_addr* addr)
248 {
249 static char output[42];
250 return inet_ntop(AF_INET6, addr, output, 42);
251 }
252
253
254 #if defined(WOLFSSL_SNIFFER_STORE_DATA_CB) || defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
min(unsigned int a,unsigned int b)255 static inline unsigned int min(unsigned int a, unsigned int b)
256 {
257 return a > b ? b : a;
258 }
259 #endif
260
261
262 #ifdef WOLFSSL_SNIFFER_WATCH
myWatchCb(void * vSniffer,const unsigned char * certHash,unsigned int certHashSz,const unsigned char * certChain,unsigned int certChainSz,void * ctx,char * error)263 static int myWatchCb(void* vSniffer,
264 const unsigned char* certHash, unsigned int certHashSz,
265 const unsigned char* certChain, unsigned int certChainSz,
266 void* ctx, char* error)
267 {
268 const char* certName = NULL;
269
270 (void)certChain;
271 (void)certChainSz;
272 (void)ctx;
273
274 if (certHashSz == sizeof(rsaHash) &&
275 XMEMCMP(certHash, rsaHash, certHashSz) == 0) {
276 certName = DEFAULT_SERVER_KEY_RSA;
277 }
278 if (certHashSz == sizeof(eccHash) &&
279 XMEMCMP(certHash, eccHash, certHashSz) == 0) {
280 certName = DEFAULT_SERVER_KEY_ECC;
281 }
282
283 if (certName == NULL) {
284 /* don't return error if key is not loaded */
285 printf("Warning: No matching key found for cert hash\n");
286 return 0;
287 }
288
289 return ssl_SetWatchKey_file(vSniffer, certName, FILETYPE_PEM, NULL, error);
290 }
291 #endif /* WOLFSSL_SNIFFER_WATCH */
292
293
294 #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
myStoreDataCb(const unsigned char * decryptBuf,unsigned int decryptBufSz,unsigned int decryptBufOffset,void * ctx)295 static int myStoreDataCb(const unsigned char* decryptBuf,
296 unsigned int decryptBufSz, unsigned int decryptBufOffset, void* ctx)
297 {
298 byte** data = (byte**)ctx;
299 unsigned int qty;
300
301 if (data == NULL)
302 return -1;
303
304 if (decryptBufSz < decryptBufOffset)
305 return -1;
306
307 qty = min(decryptBufSz - decryptBufOffset, STORE_DATA_BLOCK_SZ);
308
309 if (*data == NULL) {
310 byte* tmpData;
311 tmpData = (byte*)XREALLOC(*data, decryptBufSz + 1,
312 NULL, DYNAMIC_TYPE_TMP_BUFFER);
313 if (tmpData == NULL) {
314 XFREE(*data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
315 *data = NULL;
316 return -1;
317 }
318 *data = tmpData;
319 }
320
321 XMEMCPY(*data + decryptBufOffset, decryptBuf + decryptBufOffset, qty);
322
323 return qty;
324 }
325 #endif /* WOLFSSL_SNIFFER_STORE_DATA_CB */
326
327 /* try and load as both static ephemeral and private key */
328 /* only fail if no key is loaded */
329 /* Allow comma seperated list of files */
load_key(const char * name,const char * server,int port,const char * keyFiles,const char * passwd,char * err)330 static int load_key(const char* name, const char* server, int port,
331 const char* keyFiles, const char* passwd, char* err)
332 {
333 int ret = -1;
334 int loadCount = 0;
335 char *keyFile, *ptr = NULL;
336
337 keyFile = XSTRTOK((char*)keyFiles, ",", &ptr);
338 while (keyFile != NULL) {
339 #ifdef WOLFSSL_STATIC_EPHEMERAL
340 #ifdef HAVE_SNI
341 ret = ssl_SetNamedEphemeralKey(name, server, port, keyFile,
342 FILETYPE_PEM, passwd, err);
343 #else
344 ret = ssl_SetEphemeralKey(server, port, keyFile,
345 FILETYPE_PEM, passwd, err);
346 #endif
347 if (ret == 0)
348 loadCount++;
349 #endif
350 #ifdef HAVE_SNI
351 ret = ssl_SetNamedPrivateKey(name, server, port, keyFile,
352 FILETYPE_PEM, passwd, err);
353 #else
354 ret = ssl_SetPrivateKey(server, port, keyFile,
355 FILETYPE_PEM, passwd, err);
356 #endif
357 if (ret == 0)
358 loadCount++;
359
360 if (loadCount == 0) {
361 printf("Failed loading private key %s: ret %d\n", keyFile, ret);
362 printf("Please run directly from sslSniffer/sslSnifferTest dir\n");
363 ret = -1;
364 }
365 else {
366 ret = 0;
367 }
368
369 keyFile = XSTRTOK(NULL, ",", &ptr);
370 }
371
372 (void)name;
373 return ret;
374 }
375
TrimNewLine(char * str)376 static void TrimNewLine(char* str)
377 {
378 word32 strSz = 0;
379 if (str)
380 strSz = (word32)XSTRLEN(str);
381 if (strSz > 0 && (str[strSz-1] == '\n' || str[strSz-1] == '\r'))
382 str[strSz-1] = '\0';
383 }
384
main(int argc,char ** argv)385 int main(int argc, char** argv)
386 {
387 int ret = 0;
388 int hadBadPacket = 0;
389 int inum = 0;
390 int port = 0;
391 int saveFile = 0;
392 int i = 0, defDev = 0;
393 int frame = ETHER_IF_FRAME_LEN;
394 char err[PCAP_ERRBUF_SIZE];
395 char filter[32];
396 const char *keyFilesSrc = NULL;
397 char keyFilesBuf[MAX_FILENAME_SZ];
398 char keyFilesUser[MAX_FILENAME_SZ];
399 const char *server = NULL;
400 const char *sniName = NULL;
401 struct bpf_program fp;
402 pcap_if_t *d;
403 pcap_addr_t *a;
404 #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
405 struct iovec chain[CHAIN_INPUT_COUNT];
406 int chainSz;
407 #endif
408
409 signal(SIGINT, sig_handler);
410
411 #ifndef _WIN32
412 ssl_InitSniffer(); /* dll load on Windows */
413 #endif
414 ssl_Trace("./tracefile.txt", err);
415 ssl_EnableRecovery(1, -1, err);
416 #ifdef WOLFSSL_SNIFFER_WATCH
417 ssl_SetWatchKeyCallback(myWatchCb, err);
418 #endif
419 #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
420 ssl_SetStoreDataCallback(myStoreDataCb);
421 #endif
422
423 if (argc == 1) {
424 char cmdLineArg[128];
425 /* normal case, user chooses device and port */
426
427 if (pcap_findalldevs(&alldevs, err) == -1)
428 err_sys("Error in pcap_findalldevs");
429
430 for (d = alldevs; d; d=d->next) {
431 printf("%d. %s", ++i, d->name);
432 if (strcmp(d->name, "lo0") == 0) {
433 defDev = i;
434 }
435 if (d->description)
436 printf(" (%s)\n", d->description);
437 else
438 printf(" (No description available)\n");
439 }
440
441 if (i == 0)
442 err_sys("No interfaces found! Make sure pcap or WinPcap is"
443 " installed correctly and you have sufficient permissions");
444
445 printf("Enter the interface number (1-%d) [default: %d]: ", i, defDev);
446 XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
447 if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin))
448 inum = XATOI(cmdLineArg);
449 if (inum == 0)
450 inum = defDev;
451 else if (inum < 1 || inum > i)
452 err_sys("Interface number out of range");
453
454 /* Jump to the selected adapter */
455 for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
456
457 pcap = pcap_create(d->name, err);
458
459 if (pcap == NULL) printf("pcap_create failed %s\n", err);
460
461 /* print out addresses for selected interface */
462 for (a = d->addresses; a; a = a->next) {
463 if (a->addr->sa_family == AF_INET) {
464 server =
465 iptos(&((struct sockaddr_in *)a->addr)->sin_addr);
466 printf("server = %s\n", server);
467 }
468 else if (a->addr->sa_family == AF_INET6) {
469 server =
470 ip6tos(&((struct sockaddr_in6 *)a->addr)->sin6_addr);
471 printf("server = %s\n", server);
472 }
473 }
474 if (server == NULL)
475 err_sys("Unable to get device IPv4 or IPv6 address");
476
477 ret = pcap_set_snaplen(pcap, 65536);
478 if (ret != 0) printf("pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
479
480 ret = pcap_set_timeout(pcap, 1000);
481 if (ret != 0) printf("pcap_set_timeout failed %s\n", pcap_geterr(pcap));
482
483 ret = pcap_set_buffer_size(pcap, 1000000);
484 if (ret != 0)
485 printf("pcap_set_buffer_size failed %s\n", pcap_geterr(pcap));
486
487 ret = pcap_set_promisc(pcap, 1);
488 if (ret != 0) printf("pcap_set_promisc failed %s\n", pcap_geterr(pcap));
489
490
491 ret = pcap_activate(pcap);
492 if (ret != 0) printf("pcap_activate failed %s\n", pcap_geterr(pcap));
493
494 printf("Enter the port to scan [default: 11111]: ");
495 XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
496 if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin)) {
497 port = XATOI(cmdLineArg);
498 }
499 if (port <= 0)
500 port = 11111;
501
502 SNPRINTF(filter, sizeof(filter), "tcp and port %d", port);
503
504 ret = pcap_compile(pcap, &fp, filter, 0, 0);
505 if (ret != 0) printf("pcap_compile failed %s\n", pcap_geterr(pcap));
506
507 ret = pcap_setfilter(pcap, &fp);
508 if (ret != 0) printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
509
510 /* optionally enter the private key to use */
511 #if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(DEFAULT_SERVER_EPH_KEY)
512 keyFilesSrc = DEFAULT_SERVER_EPH_KEY;
513 #else
514 keyFilesSrc = DEFAULT_SERVER_KEY;
515 #endif
516 printf("Enter the server key [default: %s]: ", keyFilesSrc);
517 XMEMSET(keyFilesBuf, 0, sizeof(keyFilesBuf));
518 XMEMSET(keyFilesUser, 0, sizeof(keyFilesUser));
519 if (XFGETS(keyFilesUser, sizeof(keyFilesUser), stdin)) {
520 TrimNewLine(keyFilesUser);
521 if (XSTRLEN(keyFilesUser) > 0) {
522 keyFilesSrc = keyFilesUser;
523 }
524 }
525 XSTRNCPY(keyFilesBuf, keyFilesSrc, sizeof(keyFilesBuf));
526
527 /* optionally enter a named key (SNI) */
528 #if !defined(WOLFSSL_SNIFFER_WATCH) && defined(HAVE_SNI)
529 printf("Enter alternate SNI [default: none]: ");
530 XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
531 if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin)) {
532 TrimNewLine(cmdLineArg);
533 if (XSTRLEN(cmdLineArg) > 0) {
534 sniName = cmdLineArg;
535 }
536 }
537 #endif /* !WOLFSSL_SNIFFER_WATCH && HAVE_SNI */
538
539 /* get IPv4 or IPv6 addresses for selected interface */
540 for (a = d->addresses; a; a = a->next) {
541 server = NULL;
542 if (a->addr->sa_family == AF_INET) {
543 server =
544 iptos(&((struct sockaddr_in *)a->addr)->sin_addr);
545 }
546 else if (a->addr->sa_family == AF_INET6) {
547 server =
548 ip6tos(&((struct sockaddr_in6 *)a->addr)->sin6_addr);
549 }
550
551 if (server) {
552 XSTRNCPY(keyFilesBuf, keyFilesSrc, sizeof(keyFilesBuf));
553 ret = load_key(sniName, server, port, keyFilesBuf, NULL, err);
554 if (ret != 0) {
555 exit(EXIT_FAILURE);
556 }
557 }
558 }
559 }
560 else if (argc >= 3) {
561 saveFile = 1;
562 pcap = pcap_open_offline(argv[1], err);
563 if (pcap == NULL) {
564 printf("pcap_open_offline failed %s\n", err);
565 ret = -1;
566 }
567 else {
568 const char* passwd = NULL;
569
570 /* defaults for server and port */
571 port = 443;
572 server = "127.0.0.1";
573 keyFilesSrc = argv[2];
574
575 if (argc >= 4)
576 server = argv[3];
577
578 if (argc >= 5)
579 port = XATOI(argv[4]);
580
581 if (argc >= 6)
582 passwd = argv[5];
583
584 ret = load_key(NULL, server, port, keyFilesSrc, passwd, err);
585 if (ret != 0) {
586 exit(EXIT_FAILURE);
587 }
588
589 /* Only let through TCP/IP packets */
590 ret = pcap_compile(pcap, &fp, "(ip6 or ip) and tcp", 0, 0);
591 if (ret != 0) {
592 printf("pcap_compile failed %s\n", pcap_geterr(pcap));
593 exit(EXIT_FAILURE);
594 }
595
596 ret = pcap_setfilter(pcap, &fp);
597 if (ret != 0) {
598 printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
599 exit(EXIT_FAILURE);
600 }
601 }
602 }
603 else {
604 /* usage error */
605 printf( "usage: ./snifftest or ./snifftest dump pemKey"
606 " [server] [port] [password]\n");
607 exit(EXIT_FAILURE);
608 }
609
610 if (ret != 0)
611 err_sys(err);
612
613 if (pcap_datalink(pcap) == DLT_NULL)
614 frame = NULL_IF_FRAME_LEN;
615
616 while (1) {
617 static int packetNumber = 0;
618 struct pcap_pkthdr header;
619 const unsigned char* packet = pcap_next(pcap, &header);
620 SSLInfo sslInfo;
621 packetNumber++;
622 if (packet) {
623
624 byte* data = NULL;
625
626 if (header.caplen > 40) { /* min ip(20) + min tcp(20) */
627 packet += frame;
628 header.caplen -= frame;
629 }
630 else
631 continue;
632 #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
633 {
634 unsigned int j = 0;
635 unsigned int remainder = header.caplen;
636
637 chainSz = 0;
638 do {
639 unsigned int chunkSz;
640
641 chunkSz = min(remainder, CHAIN_INPUT_CHUNK_SIZE);
642 chain[chainSz].iov_base = (void*)(packet + j);
643 chain[chainSz].iov_len = chunkSz;
644 j += chunkSz;
645 remainder -= chunkSz;
646 chainSz++;
647 } while (j < header.caplen);
648 }
649 #endif
650
651 #if defined(WOLFSSL_SNIFFER_CHAIN_INPUT) && \
652 defined(WOLFSSL_SNIFFER_STORE_DATA_CB)
653 ret = ssl_DecodePacketWithChainSessionInfoStoreData(chain, chainSz,
654 &data, &sslInfo, err);
655 #elif defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
656 (void)sslInfo;
657 ret = ssl_DecodePacketWithChain(chain, chainSz, &data, err);
658 #elif defined(WOLFSSL_SNIFFER_STORE_DATA_CB)
659 ret = ssl_DecodePacketWithSessionInfoStoreData(packet,
660 header.caplen, &data, &sslInfo, err);
661 #else
662 ret = ssl_DecodePacketWithSessionInfo(packet, header.caplen, &data,
663 &sslInfo, err);
664 #endif
665 if (ret < 0) {
666 printf("ssl_Decode ret = %d, %s\n", ret, err);
667 hadBadPacket = 1;
668 }
669 if (ret > 0) {
670 int j;
671 /* Convert non-printable data to periods. */
672 for (j = 0; j < ret; j++) {
673 if (isprint(data[j]) || isspace(data[j])) continue;
674 data[j] = '.';
675 }
676 data[ret] = 0;
677 printf("SSL App Data(%d:%d):%s\n", packetNumber, ret, data);
678 ssl_FreeZeroDecodeBuffer(&data, ret, err);
679 }
680 }
681 else if (saveFile)
682 break; /* we're done reading file */
683 }
684 FreeAll();
685
686 return hadBadPacket ? EXIT_FAILURE : EXIT_SUCCESS;
687 }
688
689 #endif /* full build */
690