16 files changed, 427 insertions, 83 deletions
diff --git a/noncore/net/wellenreiter/daemon/source/Makefile b/noncore/net/wellenreiter/daemon/source/Makefile new file mode 100644 index 0000000..dc459af --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/Makefile @@ -0,0 +1,31 @@ +# $Id$ + +CPP = g++ + +CFLAGS = +OPTIMFLAGS = -g +WARNFLAGS = -Wall -pedantic -DDEBUG +LDFLAGS = +LIBS = -lpcap +OBJ = daemon.o log.o sendgui.o getgui.o sniffer.o + +.SUFFIXES: +.PHONY: all wellenreiterd clean distclean realclean + +%.o : %.cc + $(CPP) $(CFLAGS) $(WARNFLAGS) $(OPTIMFLAGS) -c $< -o $@ + +all: wellenreiterd + +wellenreiterd: $(OBJ) + $(CPP) $(OPTIMFLAGS) $(WARNFLAGS) $(CFLAGS) $(OBJ) $(LDFLAGS) $(LIBS) -o $@ + @echo Build wellenreiterd + +clean distclean realclean: + @rm -rf wellenreiterd *~ *.o + @echo All dependent files have been removed. + +wellenreiterd.o: config.hh +serve.o: config.hh +log.o: config.hh +sendgui.o: config.hh diff --git a/noncore/net/wellenreiter/daemon/source/README b/noncore/net/wellenreiter/daemon/source/README deleted file mode 100644 index 249d950..0000000 --- a/noncore/net/wellenreiter/daemon/source/README +++ b/dev/null @@ -1,5 +0,0 @@ -compile it using: - -gcc -o sniffer ./sniffer.c -lpcap - - diff --git a/noncore/net/wellenreiter/daemon/source/TODO b/noncore/net/wellenreiter/daemon/source/TODO new file mode 100644 index 0000000..39b1a05 --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/TODO @@ -0,0 +1,5 @@ +implement communication protocol +security analysis +implement sniffer (last step) +security analysis +code cleanup
\ No newline at end of file diff --git a/noncore/net/wellenreiter/daemon/source/config.hh b/noncore/net/wellenreiter/daemon/source/config.hh new file mode 100644 index 0000000..b124f41 --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/config.hh @@ -0,0 +1,22 @@ +/* + * + * Global configuration for wellenreiter + * + * $Id$ + * + * Written by Martin J. Muench <mjm@codito.de> + * + */ + +#ifndef CONFIG_HH +#define CONFIG_HH + +#define PROGNAME "wellenreiter" /* Name of program (for syslog et.al.) */ +#define VERSION "0.2" /* Version of wellenreiter */ + +#define DAEMONPORT 37772 /* Port of Daemon */ + +#define GUIADDR "127.0.0.1" /* Adress of GUI, later specified in configfile */ +#define GUIPORT 37773 /* Port of GUI, " " */ + +#endif /* CONFIG_HH */ diff --git a/noncore/net/wellenreiter/daemon/source/daemon.cc b/noncore/net/wellenreiter/daemon/source/daemon.cc new file mode 100644 index 0000000..7972c0f --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/daemon.cc @@ -0,0 +1,82 @@ +/* + * Startup functions of wellenreiter + * + * $Id$ + */ + +#include "config.hh" +#include "daemon.hh" +#include "log.hh" +#include "sendgui.hh" +#include "getgui.hh" + +/* Main function of wellenreiterd */ +int main(int argc, char **argv) +{ + int sock, maxfd; + struct sockaddr_in *cliaddr; + socklen_t len=sizeof(struct sockaddr); + char buffer[128]; + FILE *fp=stdin; /* Will be replaced with sniffer */ + fd_set rset; + + fprintf(stderr, "wellenreiterd %s\n\n", VERSION); + + /* Setup socket for incoming commands */ + if(!commsock(&sock)) + return 0; + + log_info("Set up socket '%d' for GUI communication", sock); + + FD_ZERO(&rset); + + /* Start main loop */ + log_info("Starting main loop"); + while(1) + { + + FD_SET(sock, &rset); + FD_SET(fileno(fp), &rset); + maxfd=sock+fileno(fp)+1; + if(select(maxfd, &rset, NULL, NULL, NULL) < 0) + { + log_err("Error calling select: %s", strerror(errno)); + break; + } + + /* Got data on local socket from GUI */ + if(FD_ISSET(sock, &rset)) + { + memset(buffer, 0, sizeof(buffer)); + if(recvfrom(sock, buffer, sizeof(buffer)-1, 0, (struct sockaddr *)cliaddr, &len) < 0) + { + log_err("Cannot read from socket: %s", strerror(errno)); + break; + } + log_info("Received command from '%s': %s", inet_ntoa(cliaddr->sin_addr), buffer); + + /* Pass string to analyze function */ + commstring(buffer); + + } + + /* Will be replaced with sniffer ... later */ + if(FD_ISSET(fileno(fp), &rset)) + { + memset(buffer, 0, sizeof(buffer)); + if(fgets(buffer, sizeof(buffer) - 1, fp) == NULL) + { + log_err("Cannot read from stdin: %s", strerror(errno)); + break; + } + + /* Send string to GUI */ + sendgui("%d: %s", 1234, buffer); + + } + + } + + close(sock); + return 0; +} diff --git a/noncore/net/wellenreiter/daemon/source/daemon.hh b/noncore/net/wellenreiter/daemon/source/daemon.hh new file mode 100644 index 0000000..6776d37 --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/daemon.hh @@ -0,0 +1,16 @@ +/* $Id$ */ + +#ifndef DAEMON_HH +#define DAEMON_HH + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <unistd.h> +#include <errno.h> + +#endif /* DAEMON_HH */ diff --git a/noncore/net/wellenreiter/daemon/source/extract.h b/noncore/net/wellenreiter/daemon/source/extract.hh index c1bcdcd..21dcffa 100644 --- a/noncore/net/wellenreiter/daemon/source/extract.h +++ b/noncore/net/wellenreiter/daemon/source/extract.hh @@ -1,57 +1,60 @@ +/* $Id */ /* * Copyright (c) 1992, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#) $Header$ (LBL) */ - /* Network to host order macros */ +#ifndef EXTRACT_HH +#define EXTRACT_HH + #ifdef LBL_ALIGN #define EXTRACT_16BITS(p) \ ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | \ (u_int16_t)*((const u_int8_t *)(p) + 1))) #define EXTRACT_32BITS(p) \ ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | \ (u_int32_t)*((const u_int8_t *)(p) + 1) << 16 | \ (u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | \ (u_int32_t)*((const u_int8_t *)(p) + 3))) #else #define EXTRACT_16BITS(p) \ ((u_int16_t)ntohs(*(const u_int16_t *)(p))) #define EXTRACT_32BITS(p) \ ((u_int32_t)ntohl(*(const u_int32_t *)(p))) #endif #define EXTRACT_24BITS(p) \ ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 16 | \ (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ (u_int32_t)*((const u_int8_t *)(p) + 2))) /* Little endian protocol host order macros */ #define EXTRACT_LE_8BITS(p) (*(p)) #define EXTRACT_LE_16BITS(p) \ ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 1) << 8 | \ (u_int16_t)*((const u_int8_t *)(p) + 0))) #define EXTRACT_LE_32BITS(p) \ ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 3) << 24 | \ (u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \ (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ (u_int32_t)*((const u_int8_t *)(p) + 0))) + +#endif /* EXTRACT_HH */ diff --git a/noncore/net/wellenreiter/daemon/source/getgui.cc b/noncore/net/wellenreiter/daemon/source/getgui.cc new file mode 100644 index 0000000..f56f40b --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/getgui.cc @@ -0,0 +1,43 @@ +/* + * Setup UDP socket for commands + * Misc wrapper functions for incoming commands + * + * $Id$ + */ + +#include "config.hh" +#include "getgui.hh" +#include "log.hh" + +struct sockaddr_in saddr; + +/* Setup UDP Socket for incoming commands */ +int commsock(int *sock) +{ + + if((*sock=socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + log_err("Cannot set up socket: %s", strerror(errno)); + return 0; + } + + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = PF_INET; + saddr.sin_port = htons(DAEMONPORT); + saddr.sin_addr.s_addr = htonl(INADDR_ANY); + + if(bind(*sock,(struct sockaddr *)&saddr, sizeof(saddr)) < 0) + { + log_err("Cannot bind socket: %s", strerror(errno)); + close(*sock); + return 0; + } + + return 1; +} + +int commstring(const char *input) +{ + + return 1; +} diff --git a/noncore/net/wellenreiter/daemon/source/getgui.hh b/noncore/net/wellenreiter/daemon/source/getgui.hh new file mode 100644 index 0000000..f5a37f9 --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/getgui.hh @@ -0,0 +1,16 @@ +/* $id */ + +#ifndef GETGUI_HH +#define GETGUI_HH + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +int commsock(int *); +int commstring(const char *); + +#endif /* GETGUI_HH */ diff --git a/noncore/net/wellenreiter/daemon/source/ieee802_11.h b/noncore/net/wellenreiter/daemon/source/ieee802_11.hh index 497e6ed..3cc5343 100644 --- a/noncore/net/wellenreiter/daemon/source/ieee802_11.h +++ b/noncore/net/wellenreiter/daemon/source/ieee802_11.hh @@ -1,245 +1,250 @@ -/* @(#) $Header$ (LBL) */ +/* $Id$ */ /* * Copyright (c) 2001 * Fortress Technologies * Charlie Lenahan ( clenahan@fortresstech.com ) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +#ifndef IEEE802_11_HH +#define IEEE802_11_HH + #define IEEE802_11_FC_LEN 2 #define T_MGMT 0x0 /* management */ #define T_CTRL 0x1 /* control */ #define T_DATA 0x2 /* data */ #define T_RESV 0x3 /* reserved */ #define ST_ASSOC_REQUEST 0x0 #define ST_ASSOC_RESPONSE 0x1 #define ST_REASSOC_REQUEST 0x2 #define ST_REASSOC_RESPONSE 0x3 #define ST_PROBE_REQUEST 0x4 #define ST_PROBE_RESPONSE 0x5 /* RESERVED 0x6 */ /* RESERVED 0x7 */ #define ST_BEACON 0x8 #define ST_ATIM 0x9 #define ST_DISASSOC 0xA #define ST_AUTH 0xB #define ST_DEAUTH 0xC /* RESERVED 0xD */ /* RESERVED 0xE */ /* RESERVED 0xF */ #define CTRL_PS_POLL 0xA #define CTRL_RTS 0xB #define CTRL_CTS 0xC #define CTRL_ACK 0xD #define CTRL_CF_END 0xE #define CTRL_END_ACK 0xF /* * Bits in the frame control field. */ #define FC_VERSION(fc) ((fc) & 0x3) #define FC_TYPE(fc) (((fc) >> 2) & 0x3) #define FC_SUBTYPE(fc) (((fc) >> 4) & 0xF) #define FC_TO_DS(fc) ((fc) & 0x0100) #define FC_FROM_DS(fc) ((fc) & 0x0200) #define FC_MORE_FLAG(fc) ((fc) & 0x0400) #define FC_RETRY(fc) ((fc) & 0x0800) #define FC_POWER_MGMT(fc) ((fc) & 0x1000) #define FC_MORE_DATA(fc) ((fc) & 0x2000) #define FC_WEP(fc) ((fc) & 0x4000) #define FC_ORDER(fc) ((fc) & 0x8000) struct mgmt_header_t { u_int16_t fc; u_int16_t duration; u_int8_t da[6]; u_int8_t sa[6]; u_int8_t bssid[6]; u_int16_t seq_ctrl; }; #define MGMT_HEADER_LEN (2+2+6+6+6+2) #define CAPABILITY_ESS(cap) ((cap) & 0x0001) #define CAPABILITY_IBSS(cap) ((cap) & 0x0002) #define CAPABILITY_CFP(cap) ((cap) & 0x0004) #define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008) #define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010) struct ssid_t { u_int8_t element_id; u_int8_t length; u_char ssid[33]; /* 32 + 1 for null */ } ; struct rates_t { u_int8_t element_id; u_int8_t length; u_int8_t rate[8]; }; struct challenge_t { u_int8_t element_id; u_int8_t length; u_int8_t text[254]; /* 1-253 + 1 for null */ }; struct fh_t { u_int8_t element_id; u_int8_t length; u_int16_t dwell_time; u_int8_t hop_set; u_int8_t hop_pattern; u_int8_t hop_index; }; struct ds_t { u_int8_t element_id; u_int8_t length; u_int8_t channel; }; struct cf_t { u_int8_t element_id; u_int8_t length; u_int8_t count; u_int8_t period; u_int16_t max_duration; u_int16_t dur_remaing; }; struct tim_t { u_int8_t element_id; u_int8_t length; u_int8_t count; u_int8_t period; u_int8_t bitmap_control; u_int8_t bitmap[251]; }; #define E_SSID 0 #define E_RATES 1 #define E_FH 2 #define E_DS 3 #define E_CF 4 #define E_TIM 5 #define E_IBSS 6 #define E_CISCO 133 /* reserved 7 */ /* reserved 8 */ /* reserved 9 */ /* reserved 10 */ /* reserved 11 */ /* reserved 12 */ /* reserved 13 */ /* reserved 14 */ /* reserved 15 */ /* reserved 16 */ #define E_CHALLENGE 16 /* reserved 17 */ /* reserved 18 */ /* reserved 19 */ /* reserved 16 */ /* reserved 16 */ struct mgmt_body_t { u_int8_t timestamp[8]; u_int16_t beacon_interval; u_int16_t listen_interval; u_int16_t status_code; u_int16_t aid; u_char ap[6]; u_int16_t reason_code; u_int16_t auth_alg; u_int16_t auth_trans_seq_num; struct challenge_t challenge; u_int16_t capability_info; struct ssid_t ssid; struct rates_t rates; struct ds_t ds; struct cf_t cf; struct fh_t fh; struct tim_t tim; }; struct ctrl_rts_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t ta[6]; u_int8_t fcs[4]; }; #define CTRL_RTS_LEN (2+2+6+6+4) struct ctrl_cts_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t fcs[4]; }; #define CTRL_CTS_LEN (2+2+6+4) struct ctrl_ack_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t fcs[4]; }; #define CTRL_ACK_LEN (2+2+6+4) struct ctrl_ps_poll_t { u_int16_t fc; u_int16_t aid; u_int8_t bssid[6]; u_int8_t ta[6]; u_int8_t fcs[4]; }; #define CTRL_PS_POLL_LEN (2+2+6+6+4) struct ctrl_end_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t bssid[6]; u_int8_t fcs[4]; }; #define CTRL_END_LEN (2+2+6+6+4) struct ctrl_end_ack_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t bssid[6]; u_int8_t fcs[4]; }; #define CTRL_END_ACK_LEN (2+2+6+6+4) #define IV_IV(iv) ((iv) & 0xFFFFFF) #define IV_PAD(iv) (((iv) >> 24) & 0x3F) #define IV_KEYID(iv) (((iv) >> 30) & 0x03) + +#endif /* IEEE802_11_HH */ diff --git a/noncore/net/wellenreiter/daemon/source/log.cc b/noncore/net/wellenreiter/daemon/source/log.cc new file mode 100644 index 0000000..47589d2 --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/log.cc @@ -0,0 +1,52 @@ +/* + * Small functions to log to syslog + * + * $Id$ + */ + +#include "config.hh" +#include "log.hh" + +/* Log to syslog INFO */ +void log_info(const char *fmt,...) +{ + + char buffer[4096]; + va_list ap; + + memset(buffer, 0, sizeof(buffer)), + va_start(ap, fmt); + vsnprintf(buffer, sizeof(buffer)-1, fmt, ap); + va_end(ap); + + openlog(PROGNAME, LOG_PID, LOG_SYSLOG); + syslog(LOG_INFO, "(info) %s", buffer); + closelog(); + +#ifdef DEBUG + fprintf(stderr, "(info) %s\n", buffer); +#endif + +} + +/* Log to syslog ERR */ +void log_err(const char *fmt,...) +{ + + char buffer[4096]; + va_list ap; + + memset(buffer, 0, sizeof(buffer)); + va_start(ap, fmt); + vsnprintf(buffer, sizeof(buffer)-1, fmt, ap); + va_end(ap); + + openlog(PROGNAME, LOG_PID, LOG_SYSLOG); + syslog(LOG_INFO, "(err) %s", buffer); + closelog(); + +#ifdef DEBUG + fprintf(stderr, "(err) %s\n", buffer); +#endif + +} diff --git a/noncore/net/wellenreiter/daemon/source/log.hh b/noncore/net/wellenreiter/daemon/source/log.hh new file mode 100644 index 0000000..bdea7e4 --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/log.hh @@ -0,0 +1,14 @@ +/* $Id$ */ + +#ifndef LOG_HH +#define LOG_HH + +#include <stdio.h> +#include <syslog.h> +#include <stdarg.h> +#include <string.h> + +void log_info(const char *, ...); +void log_err(const char *, ...); + +#endif /* LOG_HH */ diff --git a/noncore/net/wellenreiter/daemon/source/sendgui.cc b/noncore/net/wellenreiter/daemon/source/sendgui.cc new file mode 100644 index 0000000..48ad5b8 --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/sendgui.cc @@ -0,0 +1,75 @@ +/* + * Send string to GUI + * + * $Id$ + */ + +#include "config.hh" +#include "sendgui.hh" +#include "log.hh" + +/* Simple dummy for alarm timer */ +static void alarmdummy(int signo) +{ + alarm (0); +} + +/* Connect to given IP on given port */ +int connect_server(int *sock, unsigned int ipaddr, int port) +{ + struct sockaddr_in saddr; + int retval=0; + + *sock = socket (PF_INET, SOCK_STREAM, 0); + saddr.sin_family = PF_INET; + saddr.sin_port = htons (port); + saddr.sin_addr.s_addr = ipaddr; + + signal (SIGALRM, alarmdummy); + siginterrupt (SIGALRM, 1); + + alarm(5); + retval=connect (*sock, (struct sockaddr *) &saddr, sizeof (saddr)); + alarm(0); + + if(retval < 0) + { + close (*sock); + return 0; + } + + return 1; +} + +/* Send a string to the GUI */ +int sendgui(const char *string, ...) +{ + int sock=0; + char buffer[4096]; + va_list ap; + + /* Generate string */ + memset(buffer, 0, sizeof(buffer)); + va_start(ap, string); + vsnprintf(buffer, sizeof(buffer)-1, string, ap); + va_end(ap); + + if(!connect_server(&sock, inet_addr(GUIADDR), GUIPORT)) + { + log_err("Connect to GUI at '%s' failed: %s", GUIADDR, strerror(errno)); + return 0; + } + + if(write(sock, buffer, sizeof(buffer)) < 0) + { + log_err("Cannot write to socket: %s", strerror(errno)); + close(sock); + return 0; + } + + if(close(sock) < 0) + log_err("Cannot close socket: %s", strerror(errno)); + + return 1; +} + diff --git a/noncore/net/wellenreiter/daemon/source/sendgui.hh b/noncore/net/wellenreiter/daemon/source/sendgui.hh new file mode 100644 index 0000000..e083704 --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/sendgui.hh @@ -0,0 +1,20 @@ +/* $Id$ */ + +#ifndef SENDGUI_HH +#define SENDGUI_HH + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <signal.h> +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> + +int connect_server(int *, unsigned int, int); +int sendgui(const char *string, ...); + +#endif /* SENDGUI_HH */ diff --git a/noncore/net/wellenreiter/daemon/source/sniffer.c b/noncore/net/wellenreiter/daemon/source/sniffer.cc index 31a5d13..c837505 100644 --- a/noncore/net/wellenreiter/daemon/source/sniffer.c +++ b/noncore/net/wellenreiter/daemon/source/sniffer.cc @@ -1,434 +1,418 @@ -/* Its just a simple rfmon mode sniffer - i hope my C is at last a bit better then in my - early days :-). - This works only with cisco wireless cards with an rfmon - able driver and not with wifi stuff. - Btw. did i mention that i hate C? - - To compile use: - gcc sniffer.c -o wlan-sniffer -lpcap - +/* + * rfmon mode sniffer + * This works only with cisco wireless cards with an rfmon + * able driver and not with wifi stuff. + * + * $Id$ */ -#include "sniffer.h" -int main(int argc, char **argv) -{ - int ret; /* return code */ - ret = card_into_monitormode (SNIFFER_DEVICE, CARD_TYPE_NG); - if (ret == -1) +#include "config.hh" +#include "sniffer.hh" +#include "ieee802_11.hh" +#include "extract.hh" + +int sniffer(void) { - exit(-1); - } + if(card_into_monitormode (SNIFFER_DEVICE, CARD_TYPE_NG) < 0) + return 0; start_sniffing (SNIFFER_DEVICE); - return 0; + return 1; } int card_into_monitormode (char * device, int cardtype) { - int ret = -1; + int datalink; /* used for getting the pcap datalink type */ char CiscoRFMON[35] = "/proc/driver/aironet/"; FILE *CISCO_CONFIG_FILE; char errbuf[PCAP_ERRBUF_SIZE]; pcap_t *handle; /* Checks if we have a device to sniff on */ if(device == NULL) { printf ("Fatal error i did not have any interfaces to sniff on\n"); - exit(1); + return 0; } /* Setting the prmiscous and up flag to the interface */ if (card_set_promisc_up (device) == 0) { printf ("Interface flags correctly set using ifconfig\n"); } /* Check the cardtype and executes the commands to go into monitor mode */ if (cardtype == CARD_TYPE_CISCO) /* I got a cisco card */ { /* bring the sniffer into rfmon mode */ snprintf(CiscoRFMON, sizeof(CiscoRFMON),DEFAULT_PATH, device); CISCO_CONFIG_FILE = fopen(CiscoRFMON,"w"); fputs ("Mode: r",CISCO_CONFIG_FILE); fputs ("Mode: y",CISCO_CONFIG_FILE); fputs ("XmitPower: 1",CISCO_CONFIG_FILE); fclose(CISCO_CONFIG_FILE); } else if (cardtype == CARD_TYPE_NG) { char wlanngcmd[62]; snprintf(wlanngcmd, sizeof(wlanngcmd),"%s %s lnxreq_wlansniff channel=1 enable=true",WLANCTL_PATH,device); - if (ret = (system (wlanngcmd)) != 0) + if (system (wlanngcmd) != 0) { printf ("\n Fatal error could not set %s in raw mode, check cardtype\n",device); - exit(1); + return 0; } } else if (cardtype == CARD_TYPE_HOSTAP) { printf ("Got a host-ap card, nothing is implemented now\n"); } /* Check the interface if it is in the correct raw mode */ handle = pcap_open_live(device, BUFSIZ, 1, 0, errbuf); /* getting the datalink type */ datalink = pcap_datalink(handle); if (datalink == DLT_IEEE802_11) /* Rawmode is IEEE802_11 */ { printf ("Your successfully listen on %s in 802.11 raw mode\n",device); pcap_close(handle); - return (0); + return 0; } else { printf ("Fatal error, cannot continue, your interface %s does not work in the correct 802.11 raw mode, check you driver please\n",device); pcap_close(handle); - exit(1); + return 0; } } int card_set_promisc_up (char * device) { int ret; char ifconfigcmd[32]; snprintf(ifconfigcmd,sizeof(ifconfigcmd),SBIN_PATH, device); ret = system (ifconfigcmd); if (ret > 0) { printf ("\nFatal error, could not execute %s please check your card,binary location and permission\n",ifconfigcmd); - exit(1); + return 0; } - return(0); + return 1; } int start_sniffing (char * device) { - int ret; /* return code */ + pcap_t *handletopcap; char errbuf[PCAP_ERRBUF_SIZE]; - struct pcap_pkthdr header; /* The header that pcap gives us */ - const u_char *packet; /* The actual packet */ /* opening the pcap for sniffing */ handletopcap = pcap_open_live(device, BUFSIZ, 1, 1000, errbuf); /* Next few lines a taken out of kismet */ #ifdef HAVE_PCAP_NONBLOCK pcap_setnonblock(handletopcap, 1, errstr); #endif /*start scanning */ pcap_loop(handletopcap,-1,process_packets,NULL); printf("\nDone processing packets... wheew!\n"); - return 0; + return 1; } void process_packets(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* packet) { u_int caplen = pkthdr->caplen; u_int length = pkthdr->len; u_int16_t fc; u_int HEADER_LENGTH; - u_short extracted_ethertype; - int snapend; - int ret; + /* pinfo holds all interresting information for us */ struct packetinfo pinfo; struct packetinfo *pinfoptr; pinfoptr=&pinfo; pinfoptr->isvalid = 0; pinfoptr->pktlen = pkthdr->len; if (caplen < IEEE802_11_FC_LEN) { /* This is a garbage packet, because is does not long enough to hold a 802.11b header */ pinfoptr->isvalid = 0; return; } /* Gets the framecontrol bits (2bytes long) */ fc = EXTRACT_LE_16BITS(packet); HEADER_LENGTH = GetHeaderLength(fc); if (caplen < HEADER_LENGTH) { /* This is a garbage packet, because it is not long enough to hold a correct header of its type */ pinfoptr->isvalid = 0; return; } /* Decode 802.11b header out of the packet */ if (decode_80211b_hdr(packet,pinfoptr) == 0) { /* Justification of the ofset to further process the packet */ length -= HEADER_LENGTH; caplen -= HEADER_LENGTH; packet += HEADER_LENGTH; } else { /* Something is wrong,could not be a correct packet */ return; } switch (FC_TYPE(fc)) { /* Is it a managemnet frame? */ case T_MGMT: switch (FC_SUBTYPE(fc)) { /* Is it a beacon frame? */ case ST_BEACON: if (handle_beacon(fc, packet,pinfoptr) ==0) { if (!strcmp(pinfoptr->desthwaddr,"ff:ff:ff:ff:ff:ff") == 0) { /* Every beacon must have the broadcast as destination so it must be a shitti packet */ pinfoptr->isvalid = 0; return; } if (pinfoptr->cap_ESS == pinfoptr->cap_IBSS) { /* Only one of both are possible, so must be a noise packet, if this comes up */ pinfoptr->isvalid = 0; return; } if (pinfoptr->channel < 1 || pinfoptr->channel > 14) { /* Only channels between 1 and 14 are possible others must be noise packets */ pinfoptr->isvalid = 0; return; } /* Here should be the infos to the gui issued */ if (pinfoptr->cap_ESS == 1 &&pinfoptr->cap_IBSS ==0) { printf ("\nHave found an accesspoint:"); } else if(pinfoptr->cap_ESS == 0 && pinfoptr->cap_IBSS == 1) { printf ("\nHave found an AD-HOC station:"); } if (strcmp (pinfoptr->ssid,NONBROADCASTING) ==0) { printf ("\n\tOn a non-broadcasting network"); } else { printf ("\n\tOn network : %s",pinfoptr->ssid); } printf ("\n\tLen SSID : %d",pinfoptr->ssid_len); printf ("\n\tOn Channel : %d",pinfoptr->channel); printf ("\n\tEncryption : %s", pinfoptr->cap_WEP ? "ON" : "OFF"); printf ("\n\tMacaddress : %s",pinfoptr->sndhwaddr); printf ("\n\tBssid : %s",pinfoptr->bssid); printf ("\n\tDest : %s\n",pinfoptr->desthwaddr); } break; default: printf("Unknown IEEE802.11 frame subtype (%d)",FC_SUBTYPE(fc)); break; } /* End of switch over different mgt frame types */ break; case T_CTRL: // decode_control_frames(fc, packet); printf ("Its a control frame"); break; case T_DATA: // decode_data_frames(fc, packet); printf ("Its a date frame"); break; default: printf("Unknown IEEE802.11 frame type (%d)",FC_TYPE(fc)); break; } } /* This decodes the 802.11b frame header out of the 802.11b packet all the infos is placed into the packetinfo structure */ int decode_80211b_hdr(const u_char *p,struct packetinfo *ppinfo) { - char * ret; - char testme[16]; const struct mgmt_header_t *mgthdr = (const struct mgmt_header_t *) p; ppinfo->fcsubtype = FC_SUBTYPE(mgthdr->fc); /* Get the sender, bssid and dest mac address */ etheraddr_string(mgthdr->bssid,ppinfo->bssid); etheraddr_string(mgthdr->da,ppinfo->desthwaddr); etheraddr_string(mgthdr->sa,ppinfo->sndhwaddr); ppinfo->fc_wep = FC_WEP(mgthdr->fc); - return(0); + return 0; } void etheraddr_string(register const u_char *ep,char * text) { static char hex[] = "0123456789abcdef"; register u_int i, j; register char *cp; char buf[sizeof("00:00:00:00:00:00")]; cp = buf; if ((j = *ep >> 4) != 0) *cp++ = hex[j]; *cp++ = hex[*ep++ & 0xf]; for (i = 5; (int)--i >= 0;) { *cp++ = ':'; if ((j = *ep >> 4) != 0) *cp++ = hex[j]; *cp++ = hex[*ep++ & 0xf]; } *cp = '\0'; strcpy(text,buf); - return; } int handle_beacon(u_int16_t fc, const u_char *p,struct packetinfo *ppinfo) { struct mgmt_body_t pbody; int offset = 0; /* Get the static informations out of the packet */ memset(&pbody, 0, sizeof(pbody)); memcpy(&pbody.timestamp, p, 8); offset += 8; pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset); offset += 2; pbody.capability_info = EXTRACT_LE_16BITS(p+offset); offset += 2; /* Gets the different flags out of the capabilities */ ppinfo->cap_ESS = CAPABILITY_ESS(pbody.capability_info); ppinfo->cap_IBSS = CAPABILITY_IBSS(pbody.capability_info); ppinfo->cap_WEP = CAPABILITY_PRIVACY(pbody.capability_info); /* Gets the tagged elements out of the packets */ while (offset + 1 < ppinfo->pktlen) { switch (*(p + offset)) { case E_SSID: memcpy(&(pbody.ssid),p+offset,2); offset += 2; if (pbody.ssid.length > 0) { memcpy(&(pbody.ssid.ssid),p+offset,pbody.ssid.length); offset += pbody.ssid.length; pbody.ssid.ssid[pbody.ssid.length]='\0'; - if (strcmp(pbody.ssid.ssid,"")==0) + if (strcmp((char *)pbody.ssid.ssid,"")==0) { ppinfo->ssid = NONBROADCASTING; } else { - ppinfo->ssid = pbody.ssid.ssid; + ppinfo->ssid = (char *)pbody.ssid.ssid; } ppinfo->ssid_len = pbody.ssid.length; } break; case E_CHALLENGE: memcpy(&(pbody.challenge),p+offset,2); offset += 2; if (pbody.challenge.length > 0) { memcpy(&(pbody.challenge.text),p+offset,pbody.challenge.length); offset += pbody.challenge.length; pbody.challenge.text[pbody.challenge.length]='\0'; } break; case E_RATES: memcpy(&(pbody.rates),p+offset,2); offset += 2; if (pbody.rates.length > 0) { memcpy(&(pbody.rates.rate),p+offset,pbody.rates.length); offset += pbody.rates.length; } break; case E_DS: memcpy(&(pbody.ds),p+offset,3); offset +=3; ppinfo->channel = pbody.ds.channel; break; case E_CF: memcpy(&(pbody.cf),p+offset,8); offset +=8; break; case E_TIM: memcpy(&(pbody.tim),p+offset,2); offset +=2; memcpy(&(pbody.tim.count),p+offset,3); offset +=3; if ((pbody.tim.length -3) > 0) { memcpy((pbody.tim.bitmap),p+(pbody.tim.length -3),(pbody.tim.length -3)); offset += pbody.tim.length -3; } break; default: -#if 0 - printf("(1) unhandled element_id (%d) ", *(p+offset) ); -#endif + offset+= *(p+offset+1) + 2; break; } /* end of switch*/ } /* end of for loop */ - return(0); - - - + return 1; } /* End of handle_beacon */ static int GetHeaderLength(u_int16_t fc) { int iLength=0; switch (FC_TYPE(fc)) { case T_MGMT: iLength = MGMT_HEADER_LEN; break; case T_CTRL: switch (FC_SUBTYPE(fc)) { case CTRL_PS_POLL: iLength = CTRL_PS_POLL_LEN; break; case CTRL_RTS: iLength = CTRL_RTS_LEN; break; case CTRL_CTS: iLength = CTRL_CTS_LEN; break; case CTRL_ACK: iLength = CTRL_ACK_LEN; break; case CTRL_CF_END: iLength = CTRL_END_LEN; break; case CTRL_END_ACK: iLength = CTRL_END_ACK_LEN; break; default: iLength = 0; break; } break; case T_DATA: if (FC_TO_DS(fc) && FC_FROM_DS(fc)) iLength = 30; else iLength = 24; break; default: printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc)); break; } return iLength; } diff --git a/noncore/net/wellenreiter/daemon/source/sniffer.h b/noncore/net/wellenreiter/daemon/source/sniffer.hh index b880b68..7f45be6 100644 --- a/noncore/net/wellenreiter/daemon/source/sniffer.h +++ b/noncore/net/wellenreiter/daemon/source/sniffer.hh @@ -1,102 +1,83 @@ -// Wellenreiter-sniffer-code header file +/* $Id$ */ + +#ifndef SNIFFER_HH +#define SNIFFER_HH #include <string.h> #include <stdio.h> #include <stdlib.h> #include <pcap.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/bpf.h> -#include "ieee802_11.h" -#include "extract.h" #define DEFAULT_PATH "/proc/driver/aironet/%s/Config" #define CARD_TYPE_CISCO 1 #define CARD_TYPE_NG 2 #define CARD_TYPE_HOSTAP 3 #define NONBROADCASTING "non-broadcasting" /* only for now, until we have the daemon running */ /*the config file should provide these information */ #define SNIFFER_DEVICE "wlan0" #define CARD_TYPE CARD_TYPE_CISCO #define SBIN_PATH "/sbin/ifconfig %s promisc up" #define WLANCTL_PATH "/sbin/wlanctl-ng" /* holds all the interresting data */ struct packetinfo { int isvalid; int pktlen; int fctype; int fcsubtype; int fc_wep; int cap_WEP; int cap_IBSS; int cap_ESS; int channel; char bssid[sizeof("00:00:00:00:00:00")]; char desthwaddr[sizeof("00:00:00:00:00:00")]; char sndhwaddr[sizeof("00:00:00:00:00:00")]; char *ssid; int ssid_len; }; /* Prototypes */ -int card_into_monitormode (char * device, int cardtype); +int sniffer(void); +int card_into_monitormode (char * device, int cardtype); int card_set_promisc_up (char * device); - int start_sniffing (char * device); - void process_packets(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* packet); - int decode_80211b_hdr(const u_char *p,struct packetinfo *ppinfo); - void etheraddr_string(register const u_char *ep,char * text); - int handle_beacon(u_int16_t fc, const u_char *p,struct packetinfo *ppinfo); static int GetHeaderLength(u_int16_t fc); -static const char *subtype_text[]={ - "Assoc Request", - "Assoc Response", - "ReAssoc Request", - "ReAssoc Response", - "Probe Request", - "Probe Response", - "RESERVED", - "RESERVED", - "Beacon", - "ATIM", - "Disassociation", - "Authentication", - "DeAuthentication", - "RESERVED", - "RESERVED" -}; - /* * True if "l" bytes of "var" were captured. * * The "snapend - (l) <= snapend" checks to make sure "l" isn't so large * that "snapend - (l)" underflows. * * The check is for <= rather than < because "l" might be 0. */ #define TTEST2(var, l) (snapend - (l) <= snapend && \ (const u_char *)&(var) <= snapend - (l)) /* True if "var" was captured */ #define TTEST(var) TTEST2(var, sizeof(var)) /* Bail if "l" bytes of "var" were not captured */ #define TCHECK2(var, l) if (!TTEST2(var, l)) goto trunc /* Bail if "var" was not captured */ #define TCHECK(var) TCHECK2(var, sizeof(var)) + +#endif /* SNIFFER_HH */ |