3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
5 * This file is part of CyaSSL.
7 * CyaSSL 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.
12 * CyaSSL 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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27 #define CYASSL_SNIFFER
30 #ifndef CYASSL_SNIFFER
37 printf("do ./configure --enable-sniffer to enable build support\n");
45 /* builds on *nix too, for scanf device and port */
46 #define _CRT_SECURE_NO_WARNINGS
49 #include <pcap/pcap.h> /* pcap stuff */
50 #include <stdio.h> /* printf */
51 #include <stdlib.h> /* EXIT_SUCCESS */
52 #include <string.h> /* strcmp */
53 #include <signal.h> /* signal */
55 #include <cyassl/sniffer.h>
59 #include <arpa/inet.h>
62 typedef unsigned char byte;
65 ETHER_IF_FRAME_LEN = 14, /* ethernet interface frame length */
66 NULL_IF_FRAME_LEN = 4, /* no link interface frame length */
73 static void sig_handler(const int sig)
75 printf("SIGINT handled = %d.\n", sig);
78 pcap_freealldevs(alldevs);
86 static void err_sys(const char* msg)
88 fprintf(stderr, "%s\n", msg);
94 #define SNPRINTF _snprintf
96 #define SNPRINTF snprintf
100 static char* iptos(unsigned int addr)
102 static char output[32];
103 byte *p = (byte*)&addr;
105 SNPRINTF(output, sizeof(output), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
111 int main(int argc, char** argv)
118 int frame = ETHER_IF_FRAME_LEN;
119 char err[PCAP_ERRBUF_SIZE];
121 const char *server = NULL;
122 struct bpf_program fp;
126 signal(SIGINT, sig_handler);
129 ssl_InitSniffer(); /* dll load on Windows */
131 ssl_Trace("./tracefile.txt", err);
134 /* normal case, user chooses device and port */
136 if (pcap_findalldevs(&alldevs, err) == -1)
137 err_sys("Error in pcap_findalldevs");
139 for (d = alldevs; d; d=d->next) {
140 printf("%d. %s", ++i, d->name);
142 printf(" (%s)\n", d->description);
144 printf(" (No description available)\n");
148 err_sys("No interfaces found! Make sure pcap or WinPcap is"
149 " installed correctly and you have sufficient permissions");
151 printf("Enter the interface number (1-%d): ", i);
154 if (inum < 1 || inum > i)
155 err_sys("Interface number out of range");
157 /* Jump to the selected adapter */
158 for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
160 pcap = pcap_create(d->name, err);
162 if (pcap == NULL) printf("pcap_create failed %s\n", err);
164 /* get an IPv4 address */
165 for (a = d->addresses; a; a = a->next) {
166 switch(a->addr->sa_family)
170 iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr);
171 printf("server = %s\n", server);
179 err_sys("Unable to get device IPv4 address");
181 ret = pcap_set_snaplen(pcap, 65536);
182 if (ret != 0) printf("pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
184 ret = pcap_set_timeout(pcap, 1000);
185 if (ret != 0) printf("pcap_set_timeout failed %s\n", pcap_geterr(pcap));
187 ret = pcap_set_buffer_size(pcap, 1000000);
189 printf("pcap_set_buffer_size failed %s\n", pcap_geterr(pcap));
191 ret = pcap_set_promisc(pcap, 1);
192 if (ret != 0) printf("pcap_set_promisc failed %s\n", pcap_geterr(pcap));
195 ret = pcap_activate(pcap);
196 if (ret != 0) printf("pcap_activate failed %s\n", pcap_geterr(pcap));
198 printf("Enter the port to scan: ");
201 SNPRINTF(filter, sizeof(filter), "tcp and port %d", port);
203 ret = pcap_compile(pcap, &fp, filter, 0, 0);
204 if (ret != 0) printf("pcap_compile failed %s\n", pcap_geterr(pcap));
206 ret = pcap_setfilter(pcap, &fp);
207 if (ret != 0) printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
209 ret = ssl_SetPrivateKey(server, port, "../../certs/server-key.pem",
210 FILETYPE_PEM, NULL, err);
212 else if (argc >= 3) {
214 pcap = pcap_open_offline(argv[1], err);
216 printf("pcap_open_offline failed %s\n", err);
220 /* defaults for server and port */
222 server = "127.0.0.1";
228 port = atoi(argv[4]);
230 ret = ssl_SetPrivateKey(server, port, argv[2],
231 FILETYPE_PEM, NULL, err);
237 "usage: ./snifftest or ./snifftest dump pemKey [server] [port]\n");
244 if (pcap_datalink(pcap) == DLT_NULL)
245 frame = NULL_IF_FRAME_LEN;
248 struct pcap_pkthdr header;
249 const unsigned char* packet = pcap_next(pcap, &header);
254 if (header.caplen > 40) { /* min ip(20) + min tcp(20) */
256 header.caplen -= frame;
261 ret = ssl_DecodePacket(packet, header.caplen, data, err);
263 printf("ssl_Decode ret = %d, %s\n", ret, err);
266 printf("SSL App Data:%s\n", data);
270 break; /* we're done reading file */
276 #endif /* full build */