diff options
Diffstat (limited to 'pcap2tzsp.c')
-rw-r--r-- | pcap2tzsp.c | 124 |
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 { |