summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pcap2tzsp.c124
1 files changed, 100 insertions, 24 deletions
diff --git a/pcap2tzsp.c b/pcap2tzsp.c
index 5d8d05f..bf175ea 100644
--- a/pcap2tzsp.c
+++ b/pcap2tzsp.c
@@ -25,26 +25,68 @@
/* Basics */
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
+#include <stdint.h> /* Consider using msinttypes for Visual Studio */
#include <signal.h>
+#include <string.h>
+
+#ifdef WIN32 /* snprintf compatiblity */
+#define my_snprintf sprintf_s
+#else
+#define my_snprintf snprintf
+#endif
-/* Args parsing and basename() for usage */
-#include <getopt.h>
-#include <libgen.h>
+
+/* Packet capture stuff */
+#include <pcap.h>
/* UDP stuff */
+#ifdef WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h> /* Name resolution */
-
-/* Packet capture stuff */
-#include <pcap.h>
-#include <sys/time.h>
+#define SOCKET int
+#define INVALID_SOCKET -1
+#endif
/* Time management (for bwlimit) */
#include <time.h>
+/* Args parsing and basename() for usage */
+#ifdef WIN32
+#undef _UNICODE
+#include <getopt.h> /* Consider using getopt4win for WIN32 */
+
+ /* Poor's men hand-written basename.
+ With calloc() and this is diffent from POSIX basename() */
+ char * basename(const char *path) {
+ errno_t e;
+ size_t len1, len2;
+ char filename[256], ext[8];
+ char *res=NULL;
+
+ e=_splitpath_s(path, NULL, 0, NULL, 0, filename, 256, ext, 8);
+ if (e != 0) {
+ res=strdup("");
+ } else {
+ len1=strlen(filename);
+ len2=strlen(ext);
+ res=calloc(len1+len2 + 1, sizeof(char));
+ if ( res != NULL ) {
+ strcpy_s(res, len1+1, filename);
+ strcpy_s(res+len1, len2+1, ext);
+ }
+ }
+ return res;
+ }
+#else
+#include <getopt.h>
+#include <libgen.h>
+#endif
+
/* Option default values (as strings) */
#define DEFAULT_FILTER "not ( icmp[icmptype]=icmp-unreach or (udp and dst %s and port %s) )"
#define DEFAULT_HOST "localhost"
@@ -67,7 +109,6 @@
/*
TODO List
- * Version qui compile sous Windows
* Implémenter une bwlimit en sortie (ptks/s et/ou bytes/s)
* Calcul dynamique de MAX_TZSP_PAYLOAD
*/
@@ -82,7 +123,7 @@ typedef struct _process_packet_args {
/* Types like in libpcap because I don't want to mess around hours */
u_int captured_pkt_count;
u_int sent_pkt_count;
- int socket;
+ SOCKET socket;
} process_packet_args_t;
@@ -105,6 +146,7 @@ void usage(char progname[]) {
exit(1);
}
+
void sig_handler(int signo) {
static int pcap_break=0;
@@ -123,8 +165,15 @@ void sig_handler(int signo) {
int main(int argc, char *argv[]) {
+#ifdef WIN32
+ // Winsock2 mystic stuff
+ WSADATA wsaData = {0};
+ int iResult;
+#endif
+
/* Command line args parsing */
- int c,i,j,pcap_filter_len;
+ int c,i,j;
+ size_t pcap_filter_len; /* size_t is "mandatory" for WIN32 */
char *pcap_filter=NULL;
while (1) {
@@ -196,17 +245,30 @@ int main(int argc, char *argv[]) {
for (i=optind, j=0; i<argc; i++) {
if (i<argc-1) {
- j+=sprintf(pcap_filter+j, "%s ", argv[i]);
+ j+=my_snprintf(pcap_filter+j,pcap_filter_len-j, "%s ", argv[i]);
} else {
- j+=sprintf(pcap_filter+j, "%s", argv[i]);
+ j+=my_snprintf(pcap_filter+j,pcap_filter_len-j, "%s", argv[i]);
}
}
}
+
+#ifdef WIN32
+ // Initialize Winsock
+ iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (iResult != 0) {
+ fprintf(stderr, "WSAStartup failed: %d\n", iResult);
+ return -10;
+ }
+#endif
+
signal(SIGINT, sig_handler);
/* Run the capture loop */
start_capture_loop(pcap_filter);
+#ifdef WIN32
+ WSACleanup();
+#endif
free(opt_host);
free(opt_port);
free(opt_snaplen);
@@ -218,12 +280,15 @@ int main(int argc, char *argv[]) {
int make_dgram_socket(char host[], char service[], int hint_flags, char **resolved_address) {
- /* Code taken from Client program example of getaddrinfo(3) manpage */
+ /* Code taken from Client program example of getaddrinfo(3) manpage
+ Tweaks added for WIN32 "compatibility"
+ */
struct addrinfo hints;
struct addrinfo *result, *rp;
char hbuf[NI_MAXHOST_NUMERIC];
- int sfd, s;
+ int s;
+ SOCKET sfd = INVALID_SOCKET;
/* Obtain address(es) matching host/port */
@@ -236,7 +301,7 @@ int make_dgram_socket(char host[], char service[], int hint_flags, char **resolv
s = getaddrinfo(host, service, &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
- exit(EXIT_FAILURE);
+ return -2;
}
/* getaddrinfo() returns a list of address structures.
@@ -245,15 +310,17 @@ int make_dgram_socket(char host[], char service[], int hint_flags, char **resolv
and) try the next address. */
for (rp = result; rp != NULL; rp = rp->ai_next) {
- sfd = socket(rp->ai_family, rp->ai_socktype,
- rp->ai_protocol);
- if (sfd == -1)
+ sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (sfd == INVALID_SOCKET)
continue;
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* Success */
-
+#ifdef WIN32
+ closesocket(sfd);
+#else
close(sfd);
+#endif
}
if (rp == NULL) { /* No address succeeded */
@@ -285,7 +352,8 @@ void start_capture_loop(char *pcap_filter) {
struct bpf_program pcap_filter_prog;
struct pcap_stat stat;
process_packet_args_t process_packet_args;
- int snaplen, hints_flags, pcap_filter_len, pcap_filter_synthetised=0;
+ int snaplen, hints_flags, pcap_filter_synthetised=0;
+ size_t pcap_filter_len; /* size_t is "mandatory" for WIN32 */
memset(pcap_errbuf,0,PCAP_ERRBUF_SIZE);
memset(&process_packet_args,0,sizeof(process_packet_args_t));
@@ -310,7 +378,7 @@ void start_capture_loop(char *pcap_filter) {
/* UDP socket creation */
hints_flags=AI_NUMERICSERV | AI_ADDRCONFIG | AI_V4MAPPED;
if (opt_verbose) printf("Opening socket for sending TZSP to %s:%s\n", opt_host, opt_port);
- if ( ( process_packet_args.socket = make_dgram_socket(opt_host, opt_port, hints_flags, &resolved_address) ) == -1 ) {
+ if ( ( process_packet_args.socket = make_dgram_socket(opt_host, opt_port, hints_flags, &resolved_address) ) < 0 ) {
fprintf(stderr, "ERROR : Couldn't make a socket to %s:%s\n", opt_host, opt_port);
exit(10);
}
@@ -331,13 +399,13 @@ void start_capture_loop(char *pcap_filter) {
pcap_filter_len = strlen(DEFAULT_FILTER) -4 + strlen(resolved_address) + strlen(opt_port) + 1;
pcap_filter=calloc(pcap_filter_len, sizeof(char));
//XXX pos=snprintf(pcap_filter, pcap_filter_len, DEFAULT_FILTER, resolved_address, opt_port);
- /*res=*/ (void)sprintf(pcap_filter, DEFAULT_FILTER, resolved_address, opt_port);
+ /*res=*/ (void)my_snprintf(pcap_filter, pcap_filter_len, DEFAULT_FILTER, resolved_address, opt_port);
//printf ("DEBUG : Capture filter will be : '%s' (pcap_filter_len-res==%i)\n", pcap_filter, pcap_filter_len-res);
}
free(resolved_address);
if (opt_verbose) printf("Compiling the following capture filter : '%s'\n", pcap_filter);
- if ( pcap_compile(pcap_handle,&pcap_filter_prog,pcap_filter,1,PCAP_NETMASK_UNKNOWN) == -1 ) {
+ if ( pcap_compile(pcap_handle,&pcap_filter_prog,pcap_filter,1,0/*FIXME PCAP_NETMASK_UNKNOWN*/) == -1 ) {
fprintf(stderr,"ERROR : %s\n", pcap_geterr(pcap_handle) );
exit(22);
}
@@ -368,7 +436,11 @@ void start_capture_loop(char *pcap_filter) {
stat.ps_recv, stat.ps_drop);
pcap_close(pcap_handle);
+#ifdef WIN32
+ closesocket(process_packet_args.socket);
+#else
close(process_packet_args.socket);
+#endif
}
@@ -443,7 +515,11 @@ void process_packet(u_char *void_args, const struct pcap_pkthdr* pkthdr, const u
/* TZSP packet sending (over the UDP socket) */
tzsp_len=16+pkthdr->caplen;
+#ifdef WIN32
+ res=send(args->socket, buf, tzsp_len,0);
+#else
res=write(args->socket, buf, tzsp_len);
+#endif
if (res != tzsp_len) {
fprintf(stderr, "write() on UDP socket error (written %i of %i bytes)\n", res, tzsp_len);
} else {