snifftest.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /* snifftest.c
  2. *
  3. * Copyright (C) 2006-2017 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. #ifdef _WIN32
  26. #define WOLFSSL_SNIFFER
  27. #endif
  28. #ifndef WOLFSSL_SNIFFER
  29. /* blank build */
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. int main(void)
  33. {
  34. printf("do ./configure --enable-sniffer to enable build support\n");
  35. return EXIT_SUCCESS;
  36. }
  37. #else
  38. /* do a full build */
  39. #ifdef _MSC_VER
  40. /* builds on *nix too, for scanf device and port */
  41. #define _CRT_SECURE_NO_WARNINGS
  42. #endif
  43. #include <pcap/pcap.h> /* pcap stuff */
  44. #include <stdio.h> /* printf */
  45. #include <stdlib.h> /* EXIT_SUCCESS */
  46. #include <string.h> /* strcmp */
  47. #include <signal.h> /* signal */
  48. #include <cyassl/sniffer.h>
  49. #ifndef _WIN32
  50. #include <sys/socket.h> /* AF_INET */
  51. #include <arpa/inet.h>
  52. #include <netinet/in.h>
  53. #endif
  54. typedef unsigned char byte;
  55. enum {
  56. ETHER_IF_FRAME_LEN = 14, /* ethernet interface frame length */
  57. NULL_IF_FRAME_LEN = 4, /* no link interface frame length */
  58. };
  59. pcap_t* pcap = NULL;
  60. pcap_if_t* alldevs = NULL;
  61. static void FreeAll(void)
  62. {
  63. if (pcap)
  64. pcap_close(pcap);
  65. if (alldevs)
  66. pcap_freealldevs(alldevs);
  67. #ifndef _WIN32
  68. ssl_FreeSniffer();
  69. #endif
  70. }
  71. static void sig_handler(const int sig)
  72. {
  73. printf("SIGINT handled = %d.\n", sig);
  74. FreeAll();
  75. if (sig)
  76. exit(EXIT_SUCCESS);
  77. }
  78. static void err_sys(const char* msg)
  79. {
  80. fprintf(stderr, "%s\n", msg);
  81. if (msg)
  82. exit(EXIT_FAILURE);
  83. }
  84. #ifdef _WIN32
  85. #define SNPRINTF _snprintf
  86. #else
  87. #define SNPRINTF snprintf
  88. #endif
  89. static char* iptos(unsigned int addr)
  90. {
  91. static char output[32];
  92. byte *p = (byte*)&addr;
  93. SNPRINTF(output, sizeof(output), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  94. return output;
  95. }
  96. int main(int argc, char** argv)
  97. {
  98. int ret = 0;
  99. int hadBadPacket = 0;
  100. int inum;
  101. int port;
  102. int saveFile = 0;
  103. int i = 0;
  104. int frame = ETHER_IF_FRAME_LEN;
  105. char err[PCAP_ERRBUF_SIZE];
  106. char filter[32];
  107. const char *server = NULL;
  108. struct bpf_program fp;
  109. pcap_if_t *d;
  110. pcap_addr_t *a;
  111. signal(SIGINT, sig_handler);
  112. #ifndef _WIN32
  113. ssl_InitSniffer(); /* dll load on Windows */
  114. #endif
  115. ssl_Trace("./tracefile.txt", err);
  116. ssl_EnableRecovery(1, -1, err);
  117. if (argc == 1) {
  118. /* normal case, user chooses device and port */
  119. if (pcap_findalldevs(&alldevs, err) == -1)
  120. err_sys("Error in pcap_findalldevs");
  121. for (d = alldevs; d; d=d->next) {
  122. printf("%d. %s", ++i, d->name);
  123. if (d->description)
  124. printf(" (%s)\n", d->description);
  125. else
  126. printf(" (No description available)\n");
  127. }
  128. if (i == 0)
  129. err_sys("No interfaces found! Make sure pcap or WinPcap is"
  130. " installed correctly and you have sufficient permissions");
  131. printf("Enter the interface number (1-%d): ", i);
  132. ret = scanf("%d", &inum);
  133. if (ret != 1) {
  134. printf("scanf port failed\n");
  135. }
  136. if (inum < 1 || inum > i)
  137. err_sys("Interface number out of range");
  138. /* Jump to the selected adapter */
  139. for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
  140. pcap = pcap_create(d->name, err);
  141. if (pcap == NULL) printf("pcap_create failed %s\n", err);
  142. /* get an IPv4 address */
  143. for (a = d->addresses; a; a = a->next) {
  144. switch(a->addr->sa_family)
  145. {
  146. case AF_INET:
  147. server =
  148. iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr);
  149. printf("server = %s\n", server);
  150. break;
  151. default:
  152. break;
  153. }
  154. }
  155. if (server == NULL)
  156. err_sys("Unable to get device IPv4 address");
  157. ret = pcap_set_snaplen(pcap, 65536);
  158. if (ret != 0) printf("pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
  159. ret = pcap_set_timeout(pcap, 1000);
  160. if (ret != 0) printf("pcap_set_timeout failed %s\n", pcap_geterr(pcap));
  161. ret = pcap_set_buffer_size(pcap, 1000000);
  162. if (ret != 0)
  163. printf("pcap_set_buffer_size failed %s\n", pcap_geterr(pcap));
  164. ret = pcap_set_promisc(pcap, 1);
  165. if (ret != 0) printf("pcap_set_promisc failed %s\n", pcap_geterr(pcap));
  166. ret = pcap_activate(pcap);
  167. if (ret != 0) printf("pcap_activate failed %s\n", pcap_geterr(pcap));
  168. printf("Enter the port to scan: ");
  169. ret = scanf("%d", &port);
  170. if (ret != 1)
  171. printf("scanf port failed\n");
  172. SNPRINTF(filter, sizeof(filter), "tcp and port %d", port);
  173. ret = pcap_compile(pcap, &fp, filter, 0, 0);
  174. if (ret != 0) printf("pcap_compile failed %s\n", pcap_geterr(pcap));
  175. ret = pcap_setfilter(pcap, &fp);
  176. if (ret != 0) printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
  177. ret = ssl_SetPrivateKey(server, port, "../../certs/server-key.pem",
  178. FILETYPE_PEM, NULL, err);
  179. if (ret != 0) {
  180. printf("Please run directly from sslSniffer/sslSnifferTest dir\n");
  181. }
  182. #ifdef HAVE_SNI
  183. {
  184. char altName[128];
  185. printf("Enter alternate SNI: ");
  186. ret = scanf("%s", altName);
  187. if (strnlen(altName, 128) > 0) {
  188. ret = ssl_SetNamedPrivateKey(altName,
  189. server, port, "../../certs/server-key.pem",
  190. FILETYPE_PEM, NULL, err);
  191. if (ret != 0) {
  192. printf("Please run directly from "
  193. "sslSniffer/sslSnifferTest dir\n");
  194. }
  195. }
  196. }
  197. #endif
  198. }
  199. else if (argc >= 3) {
  200. saveFile = 1;
  201. pcap = pcap_open_offline(argv[1], err);
  202. if (pcap == NULL) {
  203. printf("pcap_open_offline failed %s\n", err);
  204. ret = -1;
  205. }
  206. else {
  207. const char* passwd = NULL;
  208. /* defaults for server and port */
  209. port = 443;
  210. server = "127.0.0.1";
  211. if (argc >= 4)
  212. server = argv[3];
  213. if (argc >= 5)
  214. port = atoi(argv[4]);
  215. if (argc >= 6)
  216. passwd = argv[5];
  217. ret = ssl_SetPrivateKey(server, port, argv[2],
  218. FILETYPE_PEM, passwd, err);
  219. }
  220. }
  221. else {
  222. /* usage error */
  223. printf( "usage: ./snifftest or ./snifftest dump pemKey"
  224. " [server] [port] [password]\n");
  225. exit(EXIT_FAILURE);
  226. }
  227. if (ret != 0)
  228. err_sys(err);
  229. if (pcap_datalink(pcap) == DLT_NULL)
  230. frame = NULL_IF_FRAME_LEN;
  231. while (1) {
  232. static int packetNumber = 0;
  233. struct pcap_pkthdr header;
  234. const unsigned char* packet = pcap_next(pcap, &header);
  235. packetNumber++;
  236. if (packet) {
  237. byte* data = NULL;
  238. if (header.caplen > 40) { /* min ip(20) + min tcp(20) */
  239. packet += frame;
  240. header.caplen -= frame;
  241. }
  242. else
  243. continue;
  244. ret = ssl_DecodePacket(packet, header.caplen, &data, err);
  245. if (ret < 0) {
  246. printf("ssl_Decode ret = %d, %s\n", ret, err);
  247. hadBadPacket = 1;
  248. }
  249. if (ret > 0) {
  250. data[ret] = 0;
  251. printf("SSL App Data(%d:%d):%s\n", packetNumber, ret, data);
  252. ssl_FreeZeroDecodeBuffer(&data, ret, err);
  253. }
  254. }
  255. else if (saveFile)
  256. break; /* we're done reading file */
  257. }
  258. FreeAll();
  259. return hadBadPacket ? EXIT_FAILURE : EXIT_SUCCESS;
  260. }
  261. #endif /* full build */